逆効果を持つawkシステムコール

逆効果を持つawkシステムコール

DATA特定のキーワード(、、)の間に複数のデータの集まりを含むデータファイルがありますEND。私はこれを使用して、そのawkチャンクから取得したファイル名に基づいてデータチャンクを別々のファイルに抽出します。一部のデータチャンクは同じ名前を共有するため、blocknameファイル( "")がすでに存在する場合は、増分整数を使用して各出力ファイルの名前を変更します。

#cat input.file
useless stuff1
DATA blockname1
data1
data1
END
useless stuff2
DATA blockname2
data2
data2
END
useless stuff3
DATA blockname1
data3
data3
END
useless stuff4

3つの出力ファイルが予想されますblockname1。 (最後のファイルに整数がどのように割り当てられるかを確認してください。)blockname2blockname1_1

#cat blockname1
DATA blockname1
data1
data1
END

(他の人もそれに応じて...)

今、次のスクリプトは私が望む方法で動作します。

awk '/DATA/,/END/ {
     if ( $1 ~ /DATA/ )
       { block=$2 ; i=0 ; file=block
         while ( system("test ! -e " file ) )
           { i++ ; file=block"_"i ; print file }
       }
       print $0 > file
     }' input.file

私の問題はwhileループとそのシステムコールにあります。

system("test -e " file)存在する場合はTRUE、fileまだ存在しない場合はFALSEになります。つまり、ループが存在する場合にのみループが実行を開始し、(新しい)ループがまだ存在しない場合は中断されます。filewhilefilefile

しかし、使用するとsystem("test -e " file)(そして使用すると冗長になりますprint file)、同じ名前の無限ループが増加し、整数のサフィックスが増加し、代わりにsystem("test !-e " file)望ましい結果が得られます。

だから私が予想したものと正反対でした。

ベストアンサー1

私の考えでは、問題は終了状態testとループ条件whileの間のTRUEとFALSEの異なる定義にありますawk

testのコマンドの終了コードは0TRUE、負のコマンドの終了コードは1FALSE です。

ただし、awkループ内ではFALSEとTRUEとwhile解釈されるため、定義は正反対です。01

たとえば、

awk '{ while ( 0 ) ; { print "0" } }' file

何の出力も生成しませんが、

awk '{ while (1) ; { print "1" } }' file

無限のsを印刷します1

したがって、最良の方法は次の組み合わせを指定することです。

while ( system("command") == 0 )

または

while ( system("command") == 1 )

それぞれ。

だから私が知っている限り

while ( system("test -e " file ) == 0 ) 

予想される動作を示します。

おすすめ記事