我有“test1.csv”,它包含
200,400,600,800
100,300,500,700
50,25,125,310
和 test2.csv 并且它包含
100,4,2,1,7
200,400,600,800
21,22,23,24,25
50,25,125,310
50,25,700,5
现在
diff test2.csv test1.csv > result.csv
不同于
diff test1.csv test2.csv > result.csv
我不知道哪个是正确的顺序,但我想要别的,上面的两个命令都会输出类似的内容
2 > 100,4,2,1,7
3 2,3c3,5
4 < 100,300,500,700
5 < 50,25,125,310
6 \ No newline at end of file
7 ---
8 > 21,22,23,24,25
9 > 50,25,125,310
我只想输出差异,因此 results.csv 应该是这样的
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5
我试过了diff -q
,diff -s
但是没有成功。顺序并不重要,重要的是我只想看到差异,没有 > 或 < 或空格。
grep -FvF
对较小的文件有效,对大文件无效
第一个文件包含超过 500 万行,第二个文件包含 1300 行。
因此 results.csv 应该有 ~4,998,700 行
我也尝试过,grep -F -x -v -f
但没有效果。
答案1
听起来像是这样的工作comm
:
$ comm -3 <(sort test1.csv) <(sort test2.csv)
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5
详见man 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)
因此,这-3
意味着只会打印某个文件所特有的行。但是,这些行会根据它们所在的文件缩进。要删除制表符,请使用:
$ comm -3 <(sort test1.csv) <(sort test2.csv) | tr -d '\t'
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5
在这种情况下,您甚至不需要对文件进行排序,您可以将上述操作简化为:
comm -3 test1.csv test2.csv | tr -d '\t' > difference.csv
答案2
使用过程替换grep
:bash
$ cat <(grep -vFf test2.csv test1.csv) <(grep -vFf test1.csv test2.csv)
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5
将输出保存为results.csv
:
cat <(grep -vFf test2.csv test1.csv) <(grep -vFf test1.csv test2.csv) >results.csv
<()
是个bash
进程替代模式grep -vFf test2.csv test1.csv
将会找到test1.csv
grep -vFf test1.csv test2.csv
将会找到test2.csv
最后我们总结一下结果
cat
或者奥利建议,您还可以使用命令分组:
$ { grep -vFf test2.csv test1.csv; grep -vFf test1.csv test2.csv; }
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5
或者只是一个接一个地运行,因为它们都写入 STDOUT,所以它们最终会被添加:
$ grep -vFf test2.csv test1.csv; grep -vFf test1.csv test2.csv
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5
答案3
如果行的顺序不相关,则使用awk
或perl
:
awk '{seen[$0]++} END {for (i in seen) {if (seen[i] == 1) {print i}}}' 1.csv 2.csv
用于grep
获取公共线并过滤掉它们:
grep -hxvFf <(grep -Fxf 1.csv 2.csv) 1.csv 2.csv
内部 grep 获取公共行,然后外部 grep 查找与这些公共行不匹配的行。
答案4
由于不需要保留顺序,因此只需:
sort test1.csv test2.csv | uniq -u
sort test1.csv test2.csv
:合并和test1.csv
排序test2.csv
uniq -u
:仅打印没有重复的行