2つのファイルのn行ごとに比較し(非対称)、コンテキストを保存します。

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つのファイル間の状況を比較し、異なる場合は、上記の例ではfileBのレコード全体(行1〜4)を保存したいと思います。line3Record1は無視され、Record2は保存されます。基本的な知識はありますが、diff可能かどうかはわかりません。まず、3行目だけを比較し、他の行-Cは無視する方法がわかりません。対称コンテキスト、つまり差の前後の行数は同じです。

UPD。最初は例で間違いをしました。レコード間に実際のファイルにはない空の行がありました。その点はお詫び申し上げます。 @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!)最適化していただければとても感謝します。

答え1

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

(入力)と(入力)の通常の処理のために、nullはスペースでRS区切られたレコード全体を読み取らせます。フィールド区切り文字を改行文字()に設定すると、その中に行全体を保存して他の行と比較できます。同じでない場合、デフォルトでは出力が印刷されます(の完全なレコード)。fileAgetlinefileB\n$3$0getlinefileB

答え2

目的のタスクを実行するPythonスクリプトは次のとおりです。

#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
"""compare.py"""

import sys

file_A = open(sys.argv[1], "r")
file_B = open(sys.argv[2], "r")

records_A = file_A.read().split("\n\n")
records_B = file_B.read().split("\n\n")

for record_A, record_B in zip(records_A, records_B):
    lines_A = record_A.split("\n")
    lines_B = record_B.split("\n")
    if lines_A[2] != lines_B[2]:
        print("{}\n".format(record_B))

次のように実行できます。

python compare.py fileA fileB

サンプルデータに対して実行すると、所望の出力が得られる。

record2 line1=header
record2 line2
record2 line3 id GHI <= this is different
record2 line4

関連情報