快速合并/连接两个表的Linux命令行

4

假设我有两个相对较大的制表符分隔文件file1.txt和file2.txt。

file1.txt
id\tcity\tcar\ttype\tmodel

file2.txt 
id\tname\trating

假设file1.txt有2000个唯一的ID,因此有2000个唯一的行;而file2.txt仅有1000个唯一的行,因此有1000个唯一的ID。是否有办法将这两个表格合并?
情况1:按照file1.txt中的ID进行合并,当file2.txt中没有ID时,用NAs填充。
情况2:按照file2.txt中的ID进行合并,只有在file2.txt中的ID将与file1.txt和file2.txt中的字段一起打印出来。
注意:合并后的新文件也应该是一个以制表符分隔的文件,并且还要有一个标题文件。 注意2:如果没有标题,我也希望能提供如何操作的建议。
谢谢!

请定义“合并”一词的含义。 - Bohemian
如何使用AWK合并两个文件?或者使用Unix的join命令合并两个文件?侧边栏中的其他问题可能也相关。 - David Z
@Bohemian,通过“merge”我指的是连接。 - Dnaiel
@DavidZaslavsky非常感谢,看起来这是一个很好的解决方案,但是join需要文件排序,而awk在没有数据时不会添加NAs。您知道一些可以添加NAs并保留制表符的解决方案吗? - Dnaiel
3个回答

10
join -j 1 <(sort file1.txt) <(sort file2.txt)

您是否采用了只使用标准Unix工具的“案例2”方法。当然,如果文件已排序,则可以省略排序。

如果包括头文件,则可能依赖于ID在排序连接头文件时为数字:

join -j 1 <(sort file1.txt) <(sort file2.txt) | sort -n

有了

  • file1.txt

    id  city    car type    model
    1   york    subaru  impreza king
    2   kampala toyota  corolla sissy
    3   luzern  chrysler    gravity falcon
    
  • file2.txt

    id  name    rating
    3   zanzini PG
    2   tara    X
    
  • output:

    id  city    car type    model   name    rating
    2   kampala toyota  corolla sissy   tara    X
    3   luzern  chrysler    gravity falcon  zanzini PG
    

提示:为了保留TAB分隔符,请使用-t选项:

 join -t'    ' ...

在SO上显示包含制表符的字符' '有点困难。可以在bash中使用^VTAB输入(例如)。


1

这对我在情况1下起作用:

join -t $'\t' -1 1 -2 1 -a 1 -a 2 <(sort fileone.txt) <(sort filetwo.txt) | sort -n -t $'\t' > filethree.txt

然后:

awk '{if(NF+0<7) printf "%s\tNA\tNA\n", $0; else print $0}' filethree.txt


0
尝试这样做:

perl -lane '
    END{print "$_$h{$_}" for sort keys %h}
    $h{$F[0]} .= "\t" .  join "\t", @F[1..$#F];
' file1.txt file2.txt

这个脚本根据ID(第一列)进行连接。


谢谢!它可以工作,但有一些注意事项:(1)如果id在file1.txt的第3列,在file2.txt的第10列怎么办?我该如何相应地更改代码?(2)它在最后输出标题而不是保持标题在第一行。我该如何让标题保持在顶部?再次感谢! - Dnaiel
哦,还有一个附加条件(3),由于某种奇怪的原因,在第1列和第2列之间的输出没有使用制表符进行分隔。 - Dnaiel
perl -v 这是 Perl,v5.8.8 版本,适用于 x86_64-linux-thread-multi 架构。 - Dnaiel
哈哈哈哈,我刚试了最新版本,但我仍然有相同的问题(1)-(3),不太确定为什么,很奇怪。 - Dnaiel
另外,如果没有数据,我该如何添加制表符分隔的NA?这可能吗?我仍然遇到在底部的标题注意事项,并且某种方式文件1和文件2的最后一列之间没有制表符,正如我所说,也没有NA...谢谢,很抱歉打扰您。 - Dnaiel
在处理之前,您可以使用Perl脚本对输入文件进行筛选以满足您的额外要求。 - Gilles Quénot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接