我有“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
:只列印沒有重複的行