Text-Processing
比較 2 個文件中的每 n 行並保存(非對稱)上下文
我有 2 個文件,每個文件都包含相同數量的 4 行記錄,順序相同:
fileA
:record1 line1=header record1 line2 X <= this is different but should be ignored record1 line3 id ABC record1 line4 record2 line1=header record2 line2 record2 line3 id DEF <= this is different record2 line4
fileB
:record1 line1=header record1 line2 Y <= this is different but should be ignored record1 line3 id ABC record1 line4 record2 line1=header record2 line2 record2 line3 id GHI <= this is different record2 line4
對於每條記錄,我想
line3
在 2 個文件之間進行比較,如果line3
不同,則保存 fileB 的整個記錄(第 1-4 行);在上面的例子中,record1 將被忽略,record2 被保存。我有基本知識,diff
但不確定它是否可行。首先,我不知道如何只比較每 3 行而忽略其他行;其次,-C
定義對稱上下文,即差異之前和之後的行數相等……升級版。最初,我的範例中有一個錯誤:在我的真實文件中沒有的記錄之間存在空白行。我為此道歉。根據@stteldriver 的回答,我有以下解決方案:
awk ' NR%4==3 { lineA3=$0; getline lineB1 < "fileB"; getline lineB2 < "fileB"; getline lineB3 < "fileB"; getline lineB4 < "fileB"; if (lineA3 != lineB3) {printf "%s\n%s\n%s\n%s\n", lineB1,lineB2,lineB3,lineB4;} }' fileA
它完美地工作!雖然程式碼很醜(我才剛剛開始學習
awk
!),如果您能優化它,將不勝感激。
對於您更新的輸入,嚴格基於 4 行記錄,您可以使用模運算來維護目前記錄的數組,並每隔 4 行檢查第 3 行是否匹配:
$ awk ' {a[FNR%4] = $0; getline b[FNR%4] < "fileB"} !(FNR%4) && b[3] != a[3] { for(i=0;i<4;i++) print b[i%4] } ' fileA record2 line1=header record2 line2 record2 line3 id GHI <= this is different record2 line4
(請注意,確實應該檢查
getline
命令的返回值,並在失敗時做一些明智的事情)。對於您最初發布的輸入,您可以使用段落模式:
$ awk -vRS= -F'\n' '{A3 = $3}; getline "fileB" > -1 && $3 != A3' fileA record2 line1=header record2 line2 record2 line3 id DEF <= this is different record2 line4
空
RS
導致讀取整個空白行分隔的記錄,用於正常處理(輸入來自fileA
)和getline
(輸入來自fileB
)。將欄位分隔符設置為換行符 (\n
) 然後我們可以保存整行$3
並與另一行進行比較。如果它們不相等,則預設列印輸出$0
(即來自getline
of的整個記錄fileB
)。