在shell中快速区分2个大文本文件?

时间:2017-02-06 18:12:21

标签: bash shell sed grep

我有2个大文件(F1和F2),每个文件有200k +行,目前我正在将F1中的每个记录与F2进行比较,以查找仅对F1唯一的记录,然后将F2与F1进行比较以查找仅对于F2。

我这样做是通过使用'while'循环读取文件的每一行,然后在文件的行上使用'grep'来查看是否找到匹配项。

如果没有不匹配,此过程大约需要3个小时才能完成,如果存在大量不匹配(文件几乎不匹配,那么200k +不匹配)可能需要6个小时。

有没有什么方法可以重写这个脚本来完成相同的功能,但速度更快?

我试图使用sed重写脚本,试图删除F2中的行,如果找到匹配项,那么在比较F2和F1时,只保留F2独有的值,但是每次迭代的F1行都会调用sed似乎没有太多提高性能。

示例:

F1包含:

A
B
E
F

F2包含:

A
Y
B
Z

我期待的输出是将F1与F2进行比较:

E
F

然后将F2与F1进行比较:

Y
Z 

4 个答案:

答案 0 :(得分:3)

您想要comm

$ cat f1
A
B
E
F
$ cat f2
A
Y
B
Z
$ comm <(sort f1) <(sort f2)
                A
                B
E
F
        Y
        Z

comm输出的第1列是f1唯一的行。第2列是f2独有的那些行。第3列是在 f1 f2中找到的行。

参数-1-2-3 抑制相应的输出。例如,如果您只想 f1所特有的行,则可以过滤掉其他列:

$ comm -23 <(sort f1) <(sort f2)
E
F

请注意comm需要排序输入,我在这些示例中使用bash命令替换语法(<())提供。如果您不使用bash,请预先排序到临时文件中。

答案 1 :(得分:1)

你试过linux的差异吗? 一些有用的选项是-i,-w,-u,-y

虽然,在这种情况下,他们必须有相同的订单(你可以先排序)

答案 2 :(得分:1)

如果输出的排序顺序不重要,并且您只对两个文件中所有行的集合中唯一的排序行感兴趣,则可以执行以下操作:

sort F1 F2 | uniq -u

答案 3 :(得分:0)

如果您只是将一个或另一个文件视为模式文件,Grep将使用已编译的代码来完成您想要的全部操作。

grep -vFx -f F1.txt F2.txt

Y
Z

grep -vFx -f F2.txt F1.txt

E
F

说明:

  • -v打印与&#34;模式文件&#34;中不匹配的行 使用-f

  • 指定
  • -F - 将模式解释为固定字符串而不是正则表达式 来自this question,我正在阅读,看看是否有实际的限制。我很好奇它是否适用于两个文件中的大行计数。

  • -x - 匹配整行
  • 不需要排序。 - 您按照显示的顺序获得结果中的唯一行。此方法需要更长时间,因为它不能假设输入已排序,但如果您正在查看多行记录,则排序实际上会破坏上下文。如果文件类似,性能是可以的,因为grep -v一旦匹配&#34;模式中的任何一行就会跳过一行&#34;文件。如果文件差别很大,性能非常慢,因为它会在最终打印之前检查每个模式与每一行。