如何在 unix 中用 .txt 替换 .fam 中的列

问题描述

我正在寻找 unix 中的一些选项(可能是 awk 或 sed ),通过这些选项,我可以将 .fam 文件中的最后一列替换为 .txt 文件的最后一列 (v8)。类似于 R 中的合并函数

我的 .fam 文件看起来像这样

20481 20481 0 0 2 -9
20483 20483 0 0 1 1
20488 20488 0 0 2 1
20492 20492 0 0 1 1

我的 .txt 文件看起来像这样。

V1       V2     V3      V4      V6     V7_Pheno   V8
    2253792 20481   NA      DNA     1       Yes    2
    2253802 20483   NA      DNA     4       Yes    2
    2253816 20488   NA      DNA     0       No     1
    2253820 20492   NA      DNA     4       Yes    2

我的结果.fam 文件应该是这样的

20481 20481 0 0 2 2
20483 20483 0 0 1 2
20488 20488 0 0 2 1
20492 20492 0 0 1 2

解决方法

  • paste 合并行

  • awk 允许您选择列,所以

    paste foo.fam bar.txt | awk '{ print $1 " " $2 " " $3 " " $4 " " $13 }'
    

应该做你想做的


如果要隐藏.txt文件的标题行,可以调用tail跳过第一行:

tail -n +2 bar.txt

因此您可以将其集成到命令行中(假设您使用 bash

paste foo.fam <(tail -n +2 bar.txt) | awk '{ print $1 " " $2 " " $3 " " $4 " " $13 }'
,

awk 可以单独完成。

$: awk 'BEGIN{ getline < "f.txt" } 
     { gsub("[^ ]+$",""); l=$0; getline < "f.txt"; print l$7; }' f.fam
20481 20481 0 0 2 2
20483 20483 0 0 1 2
20488 20488 0 0 2 1
20492 20492 0 0 1 2

BEGIN 读取 .txt 上的标头记录。
然后对于 .fam 的每一行,去掉最后一个字段并保存到 l
getline 使用这种方式也解析为字段,因此 print l$7; 打印来自 .fam 的缩短记录并添加来自 .txt 的最后一个字段。