【问题标题】:How to compare one file with bunch of files in linux如何在linux中比较一个文件和一堆文件
【发布时间】:2014-12-12 03:18:34
【问题描述】:

我有一个如下图所示的fileA:

file A

chr1   123 aa b c d
chr1   234 a  b c d
chr1   345 aa b c d
chr1   456 a  b c d
....

我有一堆相似的文件,在 dirB 中有相似的列,我必须与文件 A 进行比较。

为此,我使用 cat 将 dirB 中的所有文件连接到一个名为 fileB 的文件中,然后根据键列 1 和 2 比较这两个文件,如下所示:

awk 'FNR==NR{a[$1,$2]++;next}!a[$1,$2]' fileB fileA

此命令使用第 1 列和第 2 列作为键,并给出仅在 fileA 中具有键的行。

但是,这里的问题是,当存在大量文件时,fileB 在运行的空间和内存方面非常庞大。

有人可以提出一个替代方案,这样它就可以跳过连接所有文件以创建 fileB 的步骤。相反,fileA 可以直接与 dirB 中的所有文件进行比较

chr1   123    aa    b    c    d    xxxx    abcd
chr1   234    a     b    c    d
chr1   345    aa    b    c    d    yyyy    defg
chr1   456    a    b    c    d

【问题讨论】:

  • fileA 有多大?数百万行?几十万?数十亿?
  • 你的文件名在你的awk 命令中肯定是错误的,不是吗?你不能用awk 'FNR==NR{...}...' fileA dirB/*吗?
  • 顺序很好,因为我想获得 fileA 中不在 fileB 中的唯一行。我使用了你建议的方式 dirB/* 不起作用。

标签: linux awk


【解决方案1】:

大概是这样的:

 awk 'NR == FNR { a[$1,$2] = $0; next } 
                { delete a[$1, $2] }
            END { for (i in a) print a[i] }
 ' a.txt b1.txt b2.txt ...

从文件 A 开始,将每个键添加到数组中,并将其行的内容作为值。然后对于所有 B 文件,从数组中删除具有匹配键的任何元素。最后,剩下的任何元素都是 A 中的元素,这些元素不在任何 B 文件中,因此我们可以循环并打印出来。

【讨论】:

  • 您可以有条件地将 a[key] 设置为 1,前提是它已经被看到 - 否则它看起来像 a 增长到所有文件中的键数量的大小。
  • @jas 谢谢。我尝试了您的解决方案,看起来可以正常工作。但是,我的目标是打印 a.txt 中不存在于 b1.txt、b2.txt 中的所有行......上述解决方案仅打印仅存在于 a.txt 中的关键列。你能帮忙吗
  • 当然,@user1779730,请查看更新后的答案。
猜你喜欢
  • 1970-01-01
  • 2016-01-03
  • 1970-01-01
  • 2023-03-11
  • 2015-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-01
相关资源
最近更新 更多