我有两个平面文件 A 和 B。A 是一个包含数百万条记录的大文件,B 应该是 A 的子集。A 有 20 列,具有一个唯一键,B 有 5 列,具有相同的唯一键。您能否让我知道如何比较 B 和 A,并查明文件 B 中存在的记录是否也存在于文件 A 中,并且在相应列中具有相同的数据。
答案1
我创建了两个文件来演示我的命令
file1
:
1 a1 b1 c1 d1 e1
2 a2 b2 c2 d2 e2
3 a3 b3 c3 d3 e3
4 a4 b4 c4 d4 e4
5 a5 b5 c5 d5 e5
file2
:
2 b2 c2 e2
4 b4 c4 xx
5 b5 c5 e5
第一列是唯一键。常见的列有b
、c
和e
。常见的行是2
,4
和5
。 Row4
在 column 中具有不同的值e
。
这是带有输出的命令:
$ comm -1 -3 <(cut -d' ' -f1,3,4,6 file1) file2
4 b4 c4 xx
如果文件尚未排序,那么您可以这样做:
$ comm -1 -3 <(cut -d' ' -f1,3,4,6 file1 | sort) <(sort file2)
解释:
cut -d' ' -f1,3,4,6 file1
打印文件中的字段号 1、3、4 和 6。字段由空格分隔。如果字段用逗号分隔,则使用cut
如下:cut -d','
<( ... )
comm -1 -3 file1 file2
打印 file2 特有的行。
注意事项:
cut
如果分隔符可以作为字段中的字符出现,则会出现问题。
例如:
"field1","field2,stillfield2","field3"
cut
不会理解逗号 in"field2,stillfield2"
是字段的一部分。
如果您的文件是这样的,那么也许最好使用具有内置 csv 处理功能的编程语言。例如Python。
答案2
如果文件如您所说具有不同的列,最简单的方法可能是使用您选择的语言编写一个小程序。如果文件中的行结构不相同,则不会有太大帮助diff
。comm
答案3
除了 和 解决方案之外,comm
您diff
还可以使用grep
此解决方案。
假设您的相关数据是文件 A 中的第 1,3 和 10 列以及文件 B 中的 1,2 和 3 列。我们使用cut
从 A 中选择列,将其用作关键字匹配文件并反向检查它们在文件 B 中的存在情况如果文件 B 中有一行不存在于从文件 A 中提取的匹配行中,则将显示它们。如果全部匹配,则没有输出(因为 B 应该是 A 的子集)
grep -wvf <( cut -f1,3,10 fileA ) fileB
或者,如果文件 B 的列数超过三列:
grep -wvf <( cut -f1,3,10 fileA ) <( cut -f1,2,3 fileB )