兩個大文件的差異

兩個大文件的差異

我有“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 -qdiff -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

grepbash進程替換一起使用:

$ 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

如果行的順序不相關,請使用awkperl

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

相關內容