我有两个文件
第一个文件是这样的:
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)
答案 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
相同的一般概念可以应用于diff
或comm
。但是,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.txt
和data2.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
它会打印第二个文件中找不到的内容。