Text-Processing

比較 2 個文件中的每 n 行並保存(非對稱)上下文

  • March 16, 2019

我有 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(即來自getlineof的整個記錄fileB)。

引用自:https://unix.stackexchange.com/questions/506614