ファイル名に=が含まれていると、awkが停止して待つのはなぜですか。この問題を解決する方法は?

ファイル名に=が含まれていると、awkが停止して待つのはなぜですか。この問題を解決する方法は?
awk 'processing_script_here' my=file.txt

無限に止まって待つ...
ここで何が起こっているのか、そしてどのように機能しますか?

ベストアンサー1

〜のようにクリスが言う、フォームの引数は、入力ファイル名ではなく変数の割り当て(ステートメントの前に実行された(最新の)変数の割り当てとは異なり、引数が処理されたvariablename=anythingときに実行されます)として扱われます。-v var=valueBEGIN

これは次のような場合に便利です。

awk '{print $1}' FS=/ RS='\n' file1 FS='\n' RS= file2

FSそこからファイルごとに異なるものを指定できますRS。また、一般的に次の用途に使用されます。

awk '!file1_processed{a[$0]; next}; {...}' file1 file1_processed=1 file2

より安全なバージョンは次のとおりです。

awk 'NR==FNR{a[$0]; next}; {...}' file1 file2

file1(空であれば何の効果もありません)

=ただし、ファイル名に文字が含まれていると問題が発生します。

=これは、最初の残りの部分が有効な変数名である場合にのみ問題になりますawk

では、有効な変数名の設定はawkからより厳密ですsh

POSIXでは、次のようにする必要があります。

[_a-zA-Z][_a-zA-Z0-9]*

移植可能な文字セットの文字のみを使用してください。ただし、/usr/xpg4/bin/awkSolaris 11は少なくともこの点で互換性がなく、a-zA-Zだけでなく、ロケール内のすべてのアルファベット文字を変数名に使用できます。

x+y=fooしたがって、=baror などの引数は、./foo=barまだ割り当てではない入力ファイル名として扱われます。最初の引数の残りの部分は=有効な変数名ではないからです。実装とロケールStéphane=Chazelas.txtに応じて、「may」や「not」などのパラメータです。awk

そのため、awkを使用するときは、次のものを使用することをお勧めします。

awk '...' ./*.txt

変える

awk '...' *.txt

たとえば、ファイル名に文字がtxt含まれていないことを保証できない場合は、問題を回避できます=

また、以下を-vfoo=bar.txt使用する場合は、同様のパラメーターをオプションと見なすことができます。

awk -f file.awk -vfoo=bar.txt

(1.28.0より前のbusyboxバージョンにも適用可能ですawk '{code}' -vfoo=bar.txtawk対応するエラーレポート)。

繰り返しますが、./*.txtこの問題は次の方法で解決できます(プレフィックスを使用すると、他の意味で理解されている./ファイルを呼び出すときにも役立ちます)。-awk標準入力代わりに)。

これは理由

#! /usr/bin/awk -f

Shebangsは実際には動作しません。これらの問題はvar=value次のように解決できますが、固定明細の値ARGV(./プレフィックスを追加) BEGIN:

#! /usr/bin/awk -f
BEGIN {
  for (i = 1; i < ARGC; i++)
    if (ARGV[i] ~ /^[_[:alpha:]][_[:alnum:]]*=/)
      ARGV[i] = "./" ARGV[i]
}
# rest of awk script

これはオプションには役立ちません。なぜなら、そのオプションはスクリプトawkではなくawkスクリプトによって表示されるからです。

この接頭辞を使用するときに./発生する可能性のある外観上の問題の1つはで終わることです。ただし、不要な場合はFILENAMEいつでもこのプレフィックスを使用して削除できます。substr(FILENAME, 3)

GNU実装はawkオプションを介してこれらすべての問題を解決します-E

その後、-Egawkはスクリプトパスawk-まだstdinを意味します)と入力ファイルパスのリストのみを期待します(-特別な処理もしません)。

これは以下のために設計されています:

#! /usr/bin/gawk -E

引数リストが常に入力ファイルであるshebangs(ARGVステートメント内でリストを自由に編集できることに注意してくださいBEGIN)。

次のように使用することもできます。

gawk -e '...awk code here...' -E /dev/null *.txt

後続のスクリプトに文字が含まれていても、常に入力ファイルとして処理されるように空の-Eスクリプト()を使用します。/dev/null*.txt=

おすすめ記事