タイトルと構造が同じ2つのファイルがあり、最初の列はキーです。
ファイル1:
key val1 val2 val3 val4 val5
Item1 10 12 44 88 22
Item2 33 33 43 77 22
Item3 28 44 55 22 11
Item4 12 55 55 14 44
ファイル2:
key val1 val2 val3 val4 val5
Item1 10 11 44 99 22
Item2 33 33 43 77 22
Item3 28 44 55 22 11
Item4 12 55 55 14 00
上記のファイルからわかるように、2つのファイルは2つの点で異なります。
- item1のval2とval4が異なります。
- 項目4のval5が異なります。
だから、どの項目のどのフィールドが異なるかを示す比較出力を生成したいと思います。出力は次のようになります。
Item1: val2,val4
Item4: val5
答え1
awk -v ref=file1 '
{
getline refline <ref
if (NR == 1) split(refline, head)
nf = split(refline, a)
for (i = 1; i <= nf; ++i)
if ($i != a[i])
diffcol[++n] = i
if (n > 0) {
$0 = a[1]
for (i = 1; i <= n; ++i)
$(i+1) = head[diffcol[i]]
print
n = 0
}
}' file2
これにより、ファイルがfile2
「参照ファイル」と比較されますfile1
。 fromの行file2
は一般的に読み込まれますが、fromの行はawk
コード内の呼び出しと分割によってfile1
明示的に読み取られます。getline
awk
split
このsplit(refline, head)
ブロックは配列をhead
ヘッダーに設定してから読み込みますfile1
。これは入力の最初の行でのみ行われますfile2
。
最初のループは2つのファイル間のフィールドとはdiffcol
異なり、配列に追加されたフィールドの列番号を比較します。
1つ以上の違いが見つかると、最初のフィールドが出力され、その後にfile1
他のフィールドのヘッダーが出力されます。file1
コードの書き方、ヘッダー行、および最初のフィールドも比較対象であるため、最初のフィールドで違いが見つかった場合は、おそらくその行の先頭にkey
出力行も表示されます。最初のフィールド値file1
)。
コードでは、2つのファイルの列数が同じであるとは想定していません。
質問のデータが与えられたら、このコードから次のような出力を取得できます。
Item1 val2 val4
Item4 val5
答え2
paste
awk
すべてのレコードに同じ数のフィールドがあるとし、との組み合わせを使用します。
paste file1 file2 |
awk -F'\t' '
NR == 1 {cols = split($0, hdr) / 2; next}
{
diff = sep = ""
for (i = 2; i <= cols; i++)
if ($i "" != $(i+cols) "") {
diff = diff sep hdr[i]
sep = ","
}
if (sep) print $1": "diff
}'
比較が常に語彙的になるように""
比較の各側面に追加します。フィールドが数値のように見える場合は、そのフィールドを削除して数値で比較できます。!=
0
00
-0
inf
infinity