awkで共通キーを使用して2つのファイルをマージする方法は?

awkで共通キーを使用して2つのファイルをマージする方法は?

k1とk2という2つのファイルがあり、共通キー「ブックタイトル」に基づいてこれら2つのファイルをマージしようとしています。

k1

John | Dreaming of Day | IEEEJournal
Akon | Dreaming of Night | ACMJournal

k2

Dreaming of Day | Fiction
Dreaming of Night | Non-Fiction

kout:本のタイトルに合わせてマージする必要があります。つまりDreaming of DayDreaming of Night

John | Fiction | IEEEJournal
Akon | Non-Fiction | ACMJournal

私は次のawkスクリプトを書いた:

 awk -F"|" 'BEGIN{OFS="|"}FNR==NR{a[$1$2]=$3;next}($1$2 in a && $3=$3"|"a[$1$2])' k1 k2

しかし、これはうまくいかないようです。

答え1

これはgawk次のように動作するようですmawk

awk -F' *[|] *' -vOFS=' | ' '
  NR==FNR {a[$1]=$2;next} $2 in a {print $1, a[$2], $3}
' k2 k1
John | Fiction | IEEEJournal
Akon | Non-Fiction | ACMJournal

答え2

うまくいかないのは、ファイル1のフィールド2がファイル2のフィールド1と同じではないからです。 「|」を区切り文字として使用すると、ファイル2のフィールド1は「Dreaming of Day」、ファイル1のフィールド2は「Dreaming of Day」です。 「夢」という言葉の前には余分な空白があります。

Joinコマンドを使用して例を実行してみましたが、余分なスペースが原因で機能しません。フィールド 2 - ファイル 1 から余分なスペースを削除するか、フィールド 1 - ファイル 2 に追加のスペースを追加すると機能します。

PS1:ところで、結合を使用すると(そして余分なスペースを削除することによって)、「スクリプト」なしで必要な結果に非常に近づくことができます。

join --nocheck-order -t"|" -1 2 a.txt b.txt

出力(すべて|前の余分なスペースをすべて削除した後):

Dreaming of Day |John |IEEEJournal|Fiction
Dreaming of Night |Akon |ACMJournal|Non-Fiction

その後、-d'|'必須フィールドを切り取ることができます

PS2:データに適した「古典的な方法」が常にあります(追加スペースを削除する必要はありません)。

while IFS="|" read -r line title1 rest; do
title2=$(echo $title1)
genre=$(grep -e "$title2" b.txt |cut -f2 -d"|")
echo $line "|" $genre "|" $rest    
done <a.txt

出力:

John | Fiction | IEEEJournal
Akon | Non-Fiction | ACMJournal

関連情報