根据第一列中的值加入列,但不会使列出现两次

时间:2016-08-19 11:52:24

标签: bash join merge header-files

我有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中的列数可以更改

3 个答案:

答案 0 :(得分:0)

试试这个 -

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}'

解释 -

粘贴将文件一个接一个地放置。

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

休息只是化妆品。

答案 1 :(得分:0)

试试这个;

=SUM(B2:B5)
=SUM(B6:B9)
=SUM(B10:B13)
.
.
.

这是你的代码;

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

用awk删除IID列;

column -t

前:

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}'

答案 2 :(得分:0)

在加入之前,您可以使用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)