说,我有两个文件,想知道他们有多少相等的行。例如, file1 是
1
3
2
4
5
0
10
和 file2 包含
3
10
5
64
15
在这种情况下,答案应该是3(普通行是' 3',' 10'和' 5')。
当然,这可以通过python完成,例如,但是我很好奇从bash(使用一些标准的util或者诸如awk之类的其他东西)来做这件事。这就是我想出的:
cat file1 file2 | sort | uniq -c | awk '{if ($1 > 1) {$1=""; print $0}}' | wc -l
对于任务而言似乎太复杂了,所以我想知道是否有更简单或更优雅的方法来实现相同的结果。
P.S。将公共部分的百分比输出到每个文件中的行数也很不错,但不是必需的。
UPD:文件没有重复的行
答案 0 :(得分:11)
使用awk:
查找与2个文件相同的行awk 'a[$0]++' file1 file2
将输出3 10 15
现在,只需将其传递给wc
以获取公共线的数量:
awk 'a[$0]++' file1 file2 | wc -l
将输出3
。
<强>解释强>
这里,a
的工作方式类似于默认值为0的字典。当您编写a[$0]++
时,您将向a[$0]
添加1,但此指令返回前一个值{{ 1}}(见difference between a++ and ++a)。所以你第一次遇到某个字符串时会有0(= false),下次会有1(或更多,仍然=真)。
默认情况下,a[$0]
是输出awk 'condition' file
为真的所有行的语法。
还要注意,每次遇到新密钥时,condition
数组都会展开。在脚本结束时,数组的大小将是您在所有输入文件中拥有的唯一值的数量(在OP的示例中,它将是9)。
注意:此解决方案会计算重复项,即如果您有:
a[]
file1 | file2
1 | 3
2 | 3
3 | 3
将输出awk 'a[$0]++' file1 file2
,3 3 3
将输出awk 'a[$0]++' file1 file2 | wc -l
答案 1 :(得分:2)
使用您的输入示例,这也适用。但如果文件很大,我更喜欢别人的awk解决方案:
grep -cFwf file2 file1
使用您的输入文件,上面的行输出
3
答案 2 :(得分:1)
这是一个没有awk而是使用comm
:
comm -12 <(sort file1.txt) <(sort file2.txt) | wc -l
comm
比较两个已排序的文件。参数1,2抑制了两个文件中找到的唯一行。
输出是它们在不同行上共有的行。 wc -l
计算行数。
没有wc -l
的输出:
10
3
5
当计数(显然)时:
3
答案 3 :(得分:0)
你可以用awk完成所有事情:
awk '{ a[$0] += 1} END { c = 0; for ( i in a ) { if ( a[i] > 1 ) c++; } print c}' file1 file2
要获得百分比,这样的方法有效:
awk '{ a[$0] += 1; if (NR == FNR) { b = FILENAME; n = NR} } END { c = 0; for ( i in a ) { if ( a[i] > 1 ) c++; } print b, c/n; print FILENAME, c/FNR;}' file1 file2
和输出
file1 0.428571
file2 0.6
在你的解决方案中,你可以摆脱一只猫:
sort file1 file2| uniq -c | awk '{if ($1 > 1) {$1=""; print $0}}' | wc -l
答案 4 :(得分:0)
您还可以使用 comm 命令。请记住,您必须首先对需要比较的文件进行排序:
[gc@slave ~]$ sort a > sorted_1
[gc@slave ~]$ sort b > sorted_2
[gc@slave ~]$ comm -1 -2 sorted_1 sorted_2
10
3
5
来自man页面的comm命令: comm - 逐行比较两个排序的文件 选项:
-1 suppress column 1 (lines unique to FILE1)
-2 suppress column 2 (lines unique to FILE2)
-3 suppress column 3 (lines that appear in both files)
答案 5 :(得分:0)
如何保持简洁......
这就是所需要的:
cat file1 file2 | sort -n | uniq -d | wc -l
3
男人排序: -n, - numeric-sort - 根据字符串数值
进行比较man uniq: -d, - 重复 - 仅打印重复行
男人wc: -l, - lines - 打印换行符希望这有帮助。
编辑 - 减少一个流程(信用马丁):
sort file1 file2 | uniq -d | wc -l
答案 6 :(得分:0)
使用awk
的一种方式:
awk 'NR==FNR{a[$0]; next}$0 in a{n++}END{print n}' file1 file2
输出:
3