コマンドラインからawk変数を設定する方法は2つありますか?


10

プログラムテキストの後にawkコマンドラインで設定してawk変数を割り当てるO'Reillyの例(1997)に気づきました。動作しますが、この構文はman / info awkにはありません。見逃したことがありますか。それは低価格ですか...?マニュアルで見た唯一の構文はオプションです。-v

awk '/home/{print foo, bar}' foo="cat" bar="dog" /proc/$$/cmdline

出力: cat dog

回答:


11

それは実際にはPOSIXにありますawk(POSIX 2008へのリンク、以前のバージョンにもそれがあったと私は信じています)。オプションセクションで-v説明されていますが、もう1つの方法はオペランドセクションです。

-vファイル名の最後の割り当てには、次のような違いがあります。

  • -v

アプリケーションは、割り当て引数が割り当てオペランドと同じ形式であることを確認する必要があります。指定された変数の割り当ては、BEGINパターン(存在する場合)に関連付けられたアクションを含め、awkプログラムの実行前に行われます。このオプションは複数指定できます。

  • ファイル名と混合:

[...]そのような変数の割り当てはそれぞれ、次のファイル(ある場合)の処理の直前に行われます。したがって、最初のファイル引数の前の代入は、BEGINアクション(存在する場合)の後に実行され、最後のファイル引数の後の代入は、ENDアクション(存在する場合)の前に発生します。ファイル引数がない場合は、標準入力を処理する前に割り当てが実行されます。

例:

$ cat input 
hello
hello
$ awk -v var=one 'BEGIN{print var} /hello/{print var} END{print var}' \
    var=two input var=three input var=four
one
two
two
three
three
four

うわー!それはいくつかの興味深い制御点を追加します...それは便利になるはずです。ありがとう...
Peter.O

1
私の最初の「ワオ!」まだ保持されていますが、Arcegeの回答をさらに調査することで多少緩和されてい ます... "var = three"という名前の実際のファイルでテストしました... 変数割り当てawkであることを優先しました ...これは大きな結果です、すなわち。では、すべてのファイル名がこのフォームを持っている場合、それは無視されますと、変数が設定されます...この衝突を回避するための唯一の方法は、現在の作業ディレクトリのためにそのファイル名を確保することであると思わ必ずしなければならない前に置かれ相対パスで:./var=three
Peter.O

@ Peter.O、そうです、それも-v構文が導入された理由の1つです。-v今後は、構文を割り当てを行うための推奨される方法と考える必要があります。
dubiousjim

@ Peter.O、ファイル名が有効な変数の割り当てである場合の「問題」に関する優れた点。あなたは、ファイル名を含むシェル変数を使用しての引数として渡すことをしている場合awk、あなたは以下のキャッチを使用することができます:[ "$myfile" == "${myfile#/}" ] && myfile="./$myfile"
ワイルドカード

4

これは、外部で変数を設定する古いスタイルですawk。あいまいなため(ファイル名がの場合はどうなるかfoo=cat)、それ以降のバージョンでは-vオプションが追加されました。おそらく下位互換性のために機能するはずですが、保証はできません。そして言ったように、-vオプションは新しいので、のすべてのバージョンがawkそれをサポートするわけではありません。


ファイル名の衝突の可能性についてのあなたのコメントは良いです...私はそれをテストしました、そしてそれは間違いなく問題です。Matの回答へのコメントでそれについてもう少し書きました。この問題を強調してくれたThansk(+1)
Peter.O

2
実際、[Mat s answer](http://unix.stackexchange.com/a/34258/9537), -v`で説明したように、引数の割り当ては、いつ有効になるかが異なります。また-v、POSIXにあり、最も古いawk実装を除くすべてに存在する必要があります。./ファイル名に識別子以外の文字が含まれていることを使用または確認することは、明確にするためのおそらく最も信頼できる方法です。
jw013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.