4

このような1行のコマンドを実行しようとします

touch ./py.py; awk 'BEGIN{print FILENAME}' ./py.py 

結果が得られることを期待します./py.pyが、空白行しか得られません。ただし、BEGINブロックなしで実行すると、次のように機能します。

touch ./py.py; awk '{print FILENAME}' ./py.py

ブロックでFILENAME変数が使用できないようです。BEGIN何故ですか?BEGINブロックでその変数を使用するにはどうすればよいですか?

4

4 に答える 4

2

後知恵の利点を要約すると:

  • 以上の場合、代わりにgawk (GNU awk) 4使用すると、が定義されていることが保証されます。ただし、名前が示すように、すべての入力ファイルに対して呼び出されることに注意してください。BEGINFILEBEGINFILENAMEBEGINFILE

  • のみが提供される他のawkバリアントでは、 はその時点ではまだ定義されていません。これは、設計上、入力ファイルの処理がまだ開始されていないためです。(対照的に、ブロック内に値を持ちます。つまり、最後に処理されたファイルです。)BEGINFILENAMEFILENAME END

回避策:

組み込みの引数を介して awk に渡されるファイル名引数にアクセスできますARGV。ここでARGV[1]は、最初のファイル名引数、ARGV[2]2 番目などを報告します。

  • オプションと暗黙の stdin 入力はカウントされないstdinことに注意してください。そのため、暗黙の入力ARGV[1]では空の文字列になります。
  • 対照的に、変数の割り当てとして機能する疑似ファイル名カウントされます (例: VAR=10)。

したがって、疑似ファイル名がないと仮定ARGV[1]すると、ブロック内は、[最初の] ファイルが処理されている間の後のブロック内 BEGINと同等です。FILENAME

stdin:の暗黙的な使用に関する警告BSD awk(たとえば、OSX 上) は、暗黙的な入力を(後のブロックで)stdin空文字列として報告しますが、 andは報告します。ただし、3 つのバリアントはすべて、ファイル名引数として渡すことで明示的な入力をサポートします。この場合、3 つのバリアントすべてで戻ります。FILENAMEmawkgawk"-" stdin-FILENAME"-"

于 2014-02-04T22:14:15.380 に答える