如何比较两个大文件并将结果发送到第三个文件?

时间:2012-05-31 10:10:01

标签: linux bash shell unix

我有两个文件

第一个文件是这样的:

www.example.com
www.domain.com
www.otherexample.com
www.other-domain.com
www.other-example.com
www.exa-ample.com

第二个文件是这样的(数字之后; ;;在0-10之间):

www.example.com;;;2
www.domain.com;;;5
www.other-domain;;;0
www.exa-ample.com;;;4

我希望比较这两个文件并输出到第三个文件,如下所示:

www.otherexample.com
www.other-example.com

两个文件都有大尺寸(超过500mb)

5 个答案:

答案 0 :(得分:4)

使用comm(1)比较两个已排序的文件并给出差异。使用grep(1)sort(1)将您的文件转换为适合与comm进行比较的输入格式。使用bash中的流程替换将其绑定在一起:

comm -23 <(sort file1.txt) <(grep -o '^[^;]*' file2.txt | sort)

-23的{​​{1}}参数表示忽略两个文件(comm)和文件2唯一的行(-3)共有的行。根据您的具体规格,您可以使用-2-1-2

-3在第一个分号后删除所有内容。您可以使用grep -o '^[^;]*' file2.txt进行此操作,但如果您只是提取部分行而不添加任何其他内容,则sed(1)通常会更快。

grep需要对输入文件进行排序,因此comm用于执行此操作。输出将被排序。 sort使用特定于语言环境的排序规则,因此您可能需要根据所需的确切排序规则设置LC_ALL = C.

请注意,在您的问题中,您在文件2中有www.other-domain,但在文件1中有www.other-domain.com。我认为在给定输出的情况下,它是文件2中的拼写错误。

它并行运行所有进程并通过它们传输文件数据,因此即使文件很大,也不会占用大量内存或任何额外的磁盘空间来存储临时文件。

答案 1 :(得分:3)

如果file2中的输入包含file1内容的子集,您可以

sed 's/;.*//' file2 | fgrep -vxf - file1 >not-in-file2

相同的一般概念可以应用于diffcomm。但是,comm需要排序输入,但如果这不是问题(或者您的数据可以排序为开头),则只需预处理来自file2的数据。

sed 's/;.*//' file2.sorted | comm -12 - file1.sorted >cmp.out

输入需要排序的约束允许comm处理真正大的文件,因为它只需要在任何时候将最新数据保存在内存中。您可以使用自己的自定义awk脚本执行相同操作。

答案 2 :(得分:0)

您可以使用:

$ diff file1 file2 > file3

但是对我而言,你想忽略;;0部分,对吧? 然后你需要逐行处理剥离最后一部分,最后,与diff进行比较

答案 3 :(得分:0)

您可以使用diff命令将输出定向到第三个文件。例如,

% diff data1.txt data2.txt > diffs

diff man page显示了许多选项,可让您控制比较(处理和输出)。

基本的互动操作,未指定选项,假设您在文章data1.txtdata2.txt中的帖子中显示的数据产生:

% diff data1.txt data2.txt 

1,6d0
< www.example.com
< www.domain.com
< www.otherexample.com
< www.other-domain.com
< www.other-example.com
< www.exa-ample.com

答案 4 :(得分:0)

如果a是包含第一个内容的文件,b是包含第二个内容的文件:

while read line; do grep -q $line b || echo $line; done < a

它会打印第二个文件中找不到的内容。