计算两个文件中的相等行数

时间:2014-08-13 10:02:26

标签: bash awk

说,我有两个文件,想知道他们有多少相等的行。例如, 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:文件没有重复的行

7 个答案:

答案 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 file23 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