Linux Shell從一個文件去掉包含在另一個文件的內容

  1. 方法一:使用grep

grep -v -f file1 file2 && grep -v -f file2 file1 

參數-v,表示invert match,即反向匹配,輸出沒有匹配上的項。參數-f,表示從文件中讀取匹配模板(pattern)。方法一中的前一部分,在文件file1中匹配模板,來反向匹配文件file2中的內容,即輸出文件file2中,在file1中沒有的內容。後面的一部分同理可得,輸出文件file1中,在file2中沒有的內容。

  1. 方法二:使用comm 

comm -3 file1 file2

這個方法看起來最簡單。命令comm的功能就是,逐行比較兩個排好序的文件,默認輸出有三列:只在file1中有的行、只在file2中有的行、在file1和file2中共有的行。有參數-1 -2 -3,分別來抑制輸出對應的列。例如在我們的方法二中,實用-3參數,不輸出file1和file2中共有的部分。即能達到我們本文的目的。
但是注意到,comm比較排好序的兩個文件,comm在處理文件的時候,首先要查看文件是否有序,例如file1和file2的內容如下:

$cat file1
line1
line2
line3 

$cat file2
line0
line1
line3
line2

調用前面方法二的命令的時候,就會提示file2文件時無序的,輸出的結果如下:

$ comm -3 file1 file2
        line0
line2
comm: file 
2 is not in sorted order
        line2

如果使用--nocheck-order參數,不進行有序性檢測,結果如下:

$ comm -3 --nocheck-order file1 file2

        line0
line2

        line2

 從這個結果中我們可以看到,這還是不是我們真正想要的結果。這裏可體現comm的另一個特徵,就是逐行比較。它是對file1和file2進行逐行往下的比較,檢測是否相同。所以,在用comm的時候,要根據具體的情況進行分析了。 

  1. 方法三:使用awk

awk '{print NR, $0}' file1 file2 |sort -k2|uniq -u -f 1|sort -k1|awk '{print $2}'
或者:
awk '{
print $0}' file1 file2 |sort|uniq -u

awk把每一行看成是一個記錄(record),每個記錄使用分隔符(默認是空格)把每條記錄分成若干域。awk內置參數$0表示整行,$1、$2...分別表示各域,內置參數NR,表示記錄的計數,awk '{print NR, $0}' file1 file2表示依次讀取file1 file2,打印出每行,並且在前面添加行號。

 命令sort,就是對行進行排序,參數-k表示根據各行的第幾個參數關鍵字開進行排序,這裏的-k2表示根據第二個關鍵字開始進行排序。

命令uniq,進行報告或者忽略重複的行,參數-u,表示只是打印出唯一的行(unique lines),-f表示忽略的每行的前n個域的比較。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章