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)を保存したいと思います。line3
Record1は無視され、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
区切られたレコード全体を読み取らせます。フィールド区切り文字を改行文字()に設定すると、その中に行全体を保存して他の行と比較できます。同じでない場合、デフォルトでは出力が印刷されます(の完全なレコード)。fileA
getline
fileB
\n
$3
$0
getline
fileB
答え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