【问题标题】:Join columns according on value in first column but without having the column appearing twice根据第一列中的值连接列,但该列不出现两次
【发布时间】:2016-12-26 13:54:58
【问题描述】:

我有 3 个以空格分隔的文件。

文件 1(file1.txt):

FID IID SEX PHENOTYPE KIR2DL5 KIR2DS5 
A1 A1 0 1 1 2
A2 A2 1 2 1 2
A3 A3 0 1 1 1

文件 2 (file2.txt):

FID Bw4
A1 2
A2 1
A3 1

文件 3(file3.txt):

FID IID INFO
A1 A1 0.4
A2 A2 0.6
A3 A3 0.2

如果FID列中的值在3个文件之间相同,我想将3个文件合并到一个文件中,以便:

FID IID SEX PHENOTYPE KIR2DL5 KIR2DS5 Bw4 INFO
A1 A1 0 1 1 2 2 0.4
A2 A2 1 2 1 2 1 0.6
A3 A3 0 1 1 1 1 0.2

我知道我可以使用以下命令合并文件:

join file1.txt file2.txt | join - file3.txt > final.txt

但是通过使用此命令,它还添加了文件 3 中的 IID 列,因此出现了两次,如下所示:

FID IID SEX PHENOTYPE KIR2DL5 KIR2DS5 Bw4 IID INFO
A1 A1 0 1 1 2 2 A1 0.4
A2 A2 1 2 1 2 1 A1 0.6
A3 A3 0 1 1 1 1 A1 0.2

有没有办法加入这 3 个文件而不用两次这个列?

重要信息:

  • 并非所有 FID 在这 3 个文件之间都是相同的。

  • 文件 1 中的列数可以更改

【问题讨论】:

  • file3 的列数是静态的吗?如果是,您可以删除 file3 的第二列(请参阅man colrm)。使用 bash process substitution: join file1.txt file2.txt | join - <(colrm 2 < file3.txt)
  • "我知道我可以像这样使用 awk 合并文件:" ??没有显示 awk 代码 ;-) 祝你好运!

标签: bash join merge header-files


【解决方案1】:

试试这个-

paste file1.txt file2.txt file3.txt | awk '{ if ( $1==$7 && $1==$9) print $1 "\t" $2 "\t" $3 "\t" $4 "\t" $5 "\t" $6 "\t" $8 "\t" $11}'

说明-

paste 将文件一个接一个地放置。

awk '{ if () }' 检查条件是否为真。

休息只是化妆品。

【讨论】:

  • 如果 file1 中的列数发生变化,这也不起作用。
【解决方案2】:

试试这个;

join file1.txt file2.txt | join - file3.txt  | awk -v OFS=' ' 'NR==1{for (i=1;i<=NF;i++)if ($i=="IID"){n=i-1;m=NF-(i==NF)}} {for(i=1;i<=NF;i+=1+(i==n))printf "%s%s",$i,i==m?ORS:OFS}' | column -t

这是你的代码;

join file1.txt file2.txt | join - file3.txt

为了漂亮的格式;

column -t

用 awk 删除 IID 列;

awk -v OFS='\t' 'NR==1{for (i=1;i<=NF;i++)if ($i=="IID"){n=i-1;m=NF-(i==NF)}} {for(i=1;i<=NF;i+=1+(i==n))printf "%s%s",$i,i==m?ORS:OFS}'

例如:

user@user-host:/tmp/1$ join file1.txt file2.txt | join - file3.txt  | awk -v OFS=' ' 'NR==1{for (i=1;i<=NF;i++)if ($i=="IID"){n=i-1;m=NF-(i==NF)}} {for(i=1;i<=NF;i+=1+(i==n))printf "%s%s",$i,i==m?ORS:OFS}' | column -t
FID  IID  SEX  PHENOTYPE  KIR2DL5  KIR2DS5  Bw4  INFO
A1   A1   0    1          1        2        2    0.4
A2   A2   1    2          1        2        1    0.6
A3   A3   0    1          1        1        1    0.2

【讨论】:

  • 如果 file1 中的列数发生变化,这将不起作用。那么,它就不再是第 8 列了。
【解决方案3】:

您可以在加入前使用cut 和进程替换来删除文件3 的第二列:

$ join file1.txt file2.txt | join - <(cut --complement -d ' ' -f 2 file3.txt)
FID IID SEX PHENOTYPE KIR2DL5 KIR2DS5 Bw4 INFO
A1 A1 0 1 1 2 2 0.4
A2 A2 1 2 1 2 1 0.6
A3 A3 0 1 1 1 1 0.2

--complement 是一个 GNU 扩展。如果你不能使用它,替代方案是

join file1.txt file2.txt | join - <(cut -d ' ' -f 1,3 file3.txt)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多