2012-05-31 132 views
1

我有两个文件如何比较两个大文件并获得第三个文件的结果?

一号文件是这样的:

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 

两个文件H AVE大尺寸(超过500MB)

+0

第二个文件中是否还有第一个文件中不存在的域名?还是足以输出第一个不存在于第二个域中的域? –

回答

0

您可以使用:

$ diff file1 file2 > file3 

但它接缝我要不顾;;0一部分,对不对? 然后,你需要通过线剥离的最后一部分线处理它,最后,用diff

+0

回复:“逐行删除最后一部分”:可以用'<(cut -d';'-f1 file2)'替换'file2'来完成。 – ruakh

0

比较你可以使用diff命令,并直接输出到3第三个文件。例如,

% 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 
+0

与差异我得到的消息:差异:内存耗尽 –

+1

@MartinMocik也许你可以尝试'rdiff'根据这个职位:http://beerpla.net/2008/05/12/a-better-diff-or-what- gnu-diff-runs-out-of-memory-diff-memory-exhausted/ – Levon

0

如果a是与第一内容的文件和b是带有第二个内容的文件:

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

它打印在第二个文件中找不到的文件。

+0

对于一组500MB的文件,这将会非常慢。 –

+0

当然,但它的作品。这是一个简单的C程序的好起点 –

4

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

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

-23参数comm说忽略两者共同文件(-3)和行唯一的行到文件2(-2)。根据您的确切规格,您可以使用-1-2-3

grep -o '^[^;]*' file2.txt刚刚剥去第一个分号后的所有内容。您可以使用sed(1),但如果您只提取一行的一部分而不添加其他内容,grep通常会更快。

comm需要输入文件进行排序,所以sort是用来做到这一点。输出将被排序。sort使用语言环境特定的排序规则,因此您可能需要根据所需的精确排序规则设置LC_ALL = C。

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

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

+0

在我的系统上,花了'grep'花费的时间是'sed'的1/8。对于900KB的GNU'grep'文件,'time sed'/..////'文件名>/dev/null'与'time grep -o'^ [^;] *'filename>/dev/null' 2.5.4和GNU'sed' 4.2.1 –

+0

@ DennisWilliamson:有意思。在过去,我的工作速度快了很多。感谢您的数据。 – camh

+0

很大程度上取决于数据和其他因素。我有'grep'foo'|对于更复杂的“foo”,awk'{...}'比'awk'/ foo/{...}'快得多。 –

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脚本来做同样的事情。

相关问题