根据公共列合并两个文件

根据公共列合并两个文件

我有2个文件。文件1是:

chr19   4124051 4124250 1
chrX    154458151   154458200   2
chr22   37019451    37019600    3
chr15   74995401    74995550    4
chr12   128823901   128824100   5

文件2是:

chr19   4124051 4124250 1   CUP
chr15   74995401    74995550    4   CUP
chr12   128823901   128824100   5   CUP
chr12   122752651   122752950   8   CUP
chr13   113297001   113297350   9   CUP

我想要一个像这样的 File3:

chr19   4124051 4124250 1 CUP
chrX    154458151   154458200   2
chr22   37019451    37019600    3
chr15   74995401    74995550    4 CUP
chr12   128823901   128824100   5 CUP

我想根据 File1 的第 4 列合并两个文件,并在匹配时将 File2 的第 5 列的值添加到 File1 的最后一列。

我厌倦了这个:

awk 'FNR==NR{a[$4]=$5;next} {print $1,$2,$3,$4,a[$4]}' File2 File1 > file3

但它不起作用,它在每行下创建一个额外的行。

我也尝试了 join 命令:

join -1 4 -2 4 -o'1.1,1.2,1.3,1.4,2.5' File1 File2

它会创建一个空文件。

有什么建议么?

答案1

您的文件是在 Windows 中创建的,因此它们具有 Windows 样式的行结尾 ( \r\n)。删除\r,一切都应该按您的预期工作:

sed -i 's/\r//' File1
sed -i 's/\r//' File2
awk 'FNR==NR{a[$4]=$5;next} {print $1,$2,$3,$4,a[$4]}' File2 File1 > file3

答案2

加入+种类解决方案:

join -j4 -a1 -o1.1,1.2,1.3,1.4,2.5 <(sort -k4 File1) <(sort -k4 File2) | column -t

输出:

chr19  4124051    4124250    1  CUP
chrX   154458151  154458200  2
chr22  37019451   37019600   3
chr15  74995401   74995550   4  CUP
chr12  128823901  128824100  5  CUP

  • -j4- 从第 4 列加入

  • -a1- 从第一个文件打印不可配对的行

  • sort -k4 File1- 通过第四列/键对文件进行排序 ( -k4)

答案3

perl -F'\s+' -lane '
   s/\r$//; my $i = join $;, @F[0,3];
   @ARGV and $h{$i} = $F[4],next;
   print exists $h{$i} ? s/$/ $h{$i}/r : $_;
' File2 File1

给出:

chr19   4124051 4124250 1
chrX    154458151   154458200   2
chr22   37019451    37019600    3
chr15   74995401    74995550    4 CUP
chr12   128823901   128824100   5 CUP

相关内容