2

我有两个文件

第一个文件是这样的:

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)

4

5 回答 5

6

用于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 中的错字。

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

于 2012-05-31T10:55:42.310 回答
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脚本执行相同的操作。

于 2012-05-31T10:56:50.667 回答
0

您可以使用:

$ diff file1 file2 > file3

但我觉得你想忽略;;0一部分,对吧?然后你需要逐行处理它,剥离最后一部分,最后,与diff

于 2012-05-31T10:13:21.047 回答
0

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

% diff data1.txt data2.txt > diffs

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

没有指定选项的基本交互操作,假设您在文件中显示了您在帖子中显示的数据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
于 2012-05-31T10:13:51.083 回答
0

ifa是第一个内容b的文件,是第二个内容的文件:

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

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

于 2012-05-31T10:23:11.007 回答