シェルスクリプトの一連のパターンをawkに渡すには?

シェルスクリプトの一連のパターンをawkに渡すには?

一連のパターンが保存されており、foo.txtパターンを繰り返してファイル内の一致する行を確認したいと思いますbar.txt

while read PWW
do
   cat user/dump/bar.txt | awk '/${PWW}/{print $2}' >> user/dump/out.txt
done < user/dump/foo.txt

foo.txt:

2100001b32
2100001b38
3100001b35
4100001b28
5100001b46
6100001b56

bar.txt:

2100001b32 good
2100001b38 bad
3100001b35 okay
4100001b28 large
5100001b46 good
6100001b56 bad

期待するout.txt:

good
bad
okay
large
good
bad

から値を取得できませんfoo.txt。 whileループが実行され、空の出力が提供されます。私はそれが価値ではなく(文字通り)awk探していると思います。${PWW}foo.txt

どのように動作させることができますか?私の環境は、デフォルトawk (以前)を含むKornシェルを使用するSolaris 5.10ですawk

答え1

純粋なawkソリューションは次のとおりです。

$ awk 'FNR==NR{a[$1]=$2; next} {print a[$1]}' bar.txt foo.txt
good
bad
okay
large
good
bad

どのように動作しますか?

スクリプトは最初にbar.txtを読み取り、その情報を配列に保存しますa。その後、foo.txtを読み、その値を印刷します。

  • FNR==NR{a[$1]=$2; next}

    FNR は現在のファイルから読み取られた行数であり、NR はこれまでに読み取られた行の総数です。したがってFNR==NR、私たちはまだ最初のファイル(bar.txt)を読んでいます。その場合、その値を保持する配列に項目を追加するa[$1]=$2ために使用されます。aその後、スクリプトの残りのコマンドをスキップして再起動しますnext

  • print a[$1]

    ここに到着したら、2番目のファイルfoo.txtを読んでいます。 foo.txtを1行ずつ読みます。各行について、最初の列のキーに対応する値を見つけて印刷します。

答え2

提案を確認してください。 bashを含むUnixシェルでは、一重引用符は変更されていないテキストをプログラムに渡します(転送と言ったように)${PWW}。二重引用符は変数の拡張を可能にします。

拡張したいが${PWW}拡張したくない例では、$2次のことができます。

awk "/${PWW}/"'{print $2}'
awk /${PWW}/{print '$2'}
awk "/${PWW}/{print \$2}"

答え3

シェルから文字列値をシェルに渡す正規の方法は、オプションをawk使用することです-v var=val

パターンマッチングにこれらの文字列を使用するには(伝統的に実行されている)、行/.../全体に対して明示的な一致を作成する必要があります。

awk -v pattern=${PWW} '$0 ~ pattern {print $2}'

ちなみに、Solaris 10の場合、通常のバージョンよりも優れたエラーメッセージを取得するには、通常の古いnawkバージョンを使用することをお勧めします。awk"bailing out at ..."

関連情報