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时填写NA。

案例2。通过file2.txt中的id将它们合并,其中只有file2.txt中的id会与file1.txt和file2.txt中的字段一起打印出来。

注意:合并的新文件也应该是制表符分隔的文件,并带有头文件。笔记2。如果没有标题,我也很感激有关如何做到这一点的建议。

谢谢!

4

3 回答 3

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

您的“案例 2”是否仅使用标准的 unix 工具。当然,如果文件已排序,则可以放弃排序。

如果您包含标题,您可能会依赖数字 ID 将连接的标题排序到顶部:

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

  • 文件1.txt

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

    id  name    rating
    3   zanzini PG
    2   tara    X
    
  • 输出:

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

PS要保留 TAB 分隔符,请传递-t选项:

 join -t'    ' ...

很难在 SO 上显示 ' ' 包含 TAB 字符。键入它^VTAB(例如在 bash 中)

于 2012-11-09T01:12:20.643 回答
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

于 2012-11-09T15:52:07.830 回答
0

尝试这样做:

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

此脚本加入 ids(第一个 col)。

于 2012-11-09T00:40:44.830 回答