我在 stackoverflow 社區上找到了類似的其他鏈接,但它們沒有準確回答我的問題。
我有 2 個文件,行數不同,但我都對它們進行了排序。我的原始檔案有數百行長,但出於故障排除目的,我將 file1 設定為 12 行,file2 設定為 5 行。文件 2 是文件 1 的子集。我想要做的是運行一個命令,輸出 file1 中但不在 file2 中的所有行。
我嘗試使用 Unix 命令diff
,comm
但它們都列出了 file1 的完整內容,這不是我想要的。
一個簡單的例子是:
File1 File2
A B
B E
C I
E N
G O
I
L
M
N
O
X
所以在這裡,我們可以看到 file2 中的所有內容都在 file1 中。由於某種原因,diff
兩者comm
都顯示了 file1 的完整內容。我認為這是因為它正在進行逐行比較而不是搜尋整個文件。
我可以運行另一個 Unix 命令來輸出我所期望的結果嗎?
編輯:我用來嘗試取得所需內容的命令是:
a) 比較文件1 文件2
這基本上列出了 file1 中的所有內容,前面有一個 < 顯示內容來自 file1,而 file2 中的所有內容前面都有 >。絕對不是我需要的
b) 通訊 -23 文件1 文件2
這再次顯示了 file1 的全部內容,而不是像我預期的那樣的差異。我也
c) 通訊 -3 文件1 文件2
comm 的幫助頁面說這將列印文件1 中的行,但不會列印文件2 中的行,反之亦然,但這也沒有顯示我在範例中想要的b/c,B 出現在兩個文件中但在不同的行上。然而,輸出認為它在一個而不是另一個中,因此將其列印出來。所以輸出看起來像這樣:
A
B
B
C
E
E
etc.
這不是我所期待的。我正期待著
A
C
G
L
M
X
答案1
你可以在文件A中反向grep文件b的內容來做到這一點
例 :
francois@zaphod:/tmp$
cat > A
az
ae
ar
at
ay
au
francois@zaphod:/tmp$
cat > b
ba
by
ay
at
au
francois@zaphod:/tmp$
grep -v "$(cat /tmp/b)" /tmp/A
az
ae
ar
francois@zaphod:/tmp$
這裡的輸出只是檔案 A 中不存在於檔案 b 中的行
答案2
Diff 輸出顯示檔案 X 變成檔案 Y 必須執行的操作。
根據您的評論,您可以使用以下 oneliner:
cat x y | sort -u | cat y - | sort | uniq -u
它會
- 讀取兩個文件
- 對它們進行排序並僅列印唯一的行(
-u
按順序) - 讀取文件 (y) 並將其與管道輸出結合起來
- 度假村輸出
- 使用 uniq 以便只使用出現一次(
-u
唯一)的行。
此方法基於集合論。首先將兩組相加,然後減去其中一組。
答案3
如果其中一個文件是 DOS 格式的文字文件,而另一個文件是 Unix 格式的文字文件,則每一行都將與另一個文件中的所有行不同,即使各行上的字母相同。這是由於一個文件中每一行末尾存在額外的回車字符,而另一個文件中不存在該字符。
我期望comm -3 file1 file2
when file1
is a Unix text file while file2
is a DOS text file 得到以下輸出(這就是你所擁有的):
A
B
B
C
E
E
G
I
I
L
M
N
N
O
O
X
我期望comm -3 file1 file2
when file1
is a DOS text file while file2
is a Unix text file 得到以下輸出:
A
B
B
C
E
E
G
I
I
L
M
N
N
O
O
X
如果兩個檔案具有相同的行結尾,即它們都是 DOS 文字檔案或它們都是 Unix 文字文件,我期望的輸出comm -3 file1 file2
是
A
C
G
L
M
X
您可以使用以下命令將這兩個檔案轉換為 Unix 文字格式
dos2unix file1 file2
....假設您已經dos2unix
安裝了該實用程式。