兩個檔案必須經過排序(sort file1 > file1.sorted),否則輸出錯誤。
comm [-123] file1 file2
# 第 1 欄:僅在 file1 出現的行
# 第 2 欄:僅在 file2 出現的行
# 第 3 欄:兩檔案共有的行
| 選項 | 效果 | 等效輸出 |
|---|---|---|
-1 | 隱藏第 1 欄 | 僅顯示 file2 獨有 + 共同 |
-2 | 隱藏第 2 欄 | 僅顯示 file1 獨有 + 共同 |
-3 | 隱藏第 3 欄 | 僅顯示 file1 獨有 + file2 獨有(對稱差集) |
-12 | 隱藏 1、2 欄 | 僅顯示交集(共同行) |
-13 | 隱藏 1、3 欄 | 僅顯示 file2 獨有(差集 file2 - file1) |
-23 | 隱藏 2、3 欄 | 僅顯示 file1 獨有(差集 file1 - file2) |
-123 | 隱藏所有 | 無輸出 |
# 找出兩檔案共同的行
comm -12 file1.sorted file2.sorted
# 找出只在 file1 有的行
comm -23 file1.sorted file2.sorted
# 找出只在 file2 有的行
comm -13 file1.sorted file2.sorted
grep -v -f file1 file2
# -f file1:從 file1 讀取模式(每行一個模式)
# -v:反向匹配(顯示不匹配的行)
# 效果:輸出 file2 中「不包含 file1 任何行作為子字串」的行
| 特性 | comm | grep -f |
|---|---|---|
| 需排序 | 是 | 否 |
| 匹配方式 | 整行精確比對 | 子字串/正則比對 |
| 效能(大檔) | O(n log n) 排序 + O(n) 合併 | O(m*n) 暴力匹配,極慢 |
| 輸出格式 | 三欄制表分隔 | 原始行 |
# 內連接(交集)
join file1.sorted file2.sorted
# 左外連接
join -a 1 file1.sorted file2.sorted
# file1 獨有
awk 'NR==FNR{a[$0];next} !($0 in a)' file2 file1
# file2 獨有
awk 'NR==FNR{a[$0];next} !($0 in a)' file1 file2
# 交集
awk 'NR==FNR{a[$0];next} ($0 in a)' file1 file2
# 交集
sort file1 file2 | uniq -d
# 對稱差集(只出現一次的行)
sort file1 file2 | uniq -u
# file1 - file2
sort file1 file2 file2 | uniq -u
理解各工具的演算法複雜度與適用邊界,能讓大檔案比對從「跑半天」變成「秒出結果」。