【问题标题】:unix: merge files based on column valueunix:根据列值合并文件
【发布时间】:2012-03-21 14:32:32
【问题描述】:

我有两个文件,如下所示:

文件 1(2 列):

ID1 123
ID2 234
ID3 232
ID4 344
...

文件 2(>100 万列)

ID2 A C ...
ID3 G T ...
ID1 C T ...
ID4 A C ... 
...

我想根据 ID 将文件 1 的第 2 列中的值添加到文件 2 作为第二列。所以合并后的文件应该是这样的:

ID2 234 A C ...
ID3 232 G T ...
ID1 123 C T ...
ID4 344 A C ... 
...

因此与文件 2 完全相同(行顺序相同),但添加了第二列。 ID 是第一列的值(存在于两个文件中)。文件 1 的行数/ID 多于文件 2。文件 2 中的所有 ID 都在文件 1 中,但并非文件 1 中的所有 ID 都在文件 2 中。

有谁知道如何在 unix/bash 下做到这一点?非常感谢!

【问题讨论】:

  • 有多少行? (将文件1全部加载到内存中可行吗?)
  • 文件1有接近400万行,文件2有几万到几十万行(我实际上有几个文件2格式的文件,所以我必须多次这样做(= 每个文件))

标签: bash unix merge


【解决方案1】:
$ join <(sort file1) <(sort file2)
ID1 123 C T ...
ID2 234 A C ...
ID3 232 G T ...
ID4 344 A C ...

如果你想保持file2的顺序

$ join -1 1 -2 2 <(sort file1) <(cat -n file2 | sort -k2,2) | sort -k3,3n | cut -d' ' -f1-2,4-
ID2 234 A C ...
ID3 232 G T ...
ID1 123 C T ...
ID4 344 A C ...

【讨论】:

  • 谢谢!这似乎可行,除了由于某种原因他在添加的第二列的每个值之后开始一个新行......(所以每行现在是 2 行,第二行从“C T ...”开始)任何想法为什么会这样?
  • @Abdel,我想这是因为行尾有一个额外的 \r 。如果你先用dos2unix“处理”file1来删除那些\r,那么应该没问题。
  • 在仔细检查之后,不幸的是,他没有对所有行都这样做......合并后的文件包含的行数比原始文件 2 少(大约少 5000 行)。这并不是因为文件 1 中缺少文件 2 中的 ID(我在 SPSS 中手动检查了它,并且应该只丢失 55 个而不是 5000 个)......知道这会如何发生吗?顺便说一句,在此过程中,我还收到消息“加入:文件 1 未按排序顺序”。这可能与它有关吗?
  • @Abdel,是的,join 需要排序的文件。
  • 但是建议的命令包括排序吗?我使用了这个命令: $ join -1 1 -2 2
猜你喜欢
  • 2017-09-21
  • 2019-03-01
  • 2019-12-29
  • 2016-11-17
  • 2023-04-03
  • 2017-05-28
  • 2012-06-11
  • 2021-02-11
  • 1970-01-01
相关资源
最近更新 更多