awk 'NR%2 ...'を理解する

awk 'NR%2 ...'を理解する

こんにちは、私はBashを学ぶために「Bash Command Line and Shell Scripting Pocket Introduction」を使用していますが、偶数行を印刷するawkの章を理解していません。

注文する:

awk ' NR%2 { printf "%s", $0; print "" }' < data

コンテンツデータテキストファイル:

a,b,c,d
e,f,g,h
1,2,3,4
5,6,7,8

出力:

a,b,c,d
1,2,3,4

私の質問は、なぜ偶数行の代わりに奇数行を印刷するのですか?

私は NR%2==1 と NR%2==0 を実行し、予想通り奇数/偶数出力を提供しました。
私は何を見逃していますか?

答え1

NR~である一つに基づいてレコード(行)番号。NR % 2これを2で割って残りを返すので、奇数は1、偶数は0です。 awkでは、ゼロ以外の数字はtrueなので、最初の行、3番目の行などが印刷されます。

NR0から世紀を始めると状況が変わります。

答え2

1は「真」と見なされ、0は「偽」と見なされるためです。したがってNR % 2、ゼロ以外の場合は行が印刷され、奇数行が出力されます。

答え3

シェルスクリプトでは、0は成功を意味し、1は失敗を意味するという内容をたくさん読んだことでしょう。これは絶対に本当です。しかし、awkはシェルではありません、awkはシェルスクリプトから呼び出すことができる完全に別々のツールであり、awkは終了ステータスをテストせずにブール条件をテストします。ここで、Cや他の多くのAlgolベースの言語と同様に、ゼロ以外はtrueを意味し、0はfalseを意味します。 。

このシェルスクリプトでこれが何を意味するのかを考えてみましょう。

$ foo=0; if [ $foo ]; then echo "success"; else echo "failure"; fi
success

または均等に:

$ foo=0; if test $foo; then echo "success"; else echo "failure"; fi
success

これをawkスクリプトと比較してみてください。

$ awk 'BEGIN{ foo=0; if ( foo ) print "true"; else print "false" }'
false

どちらのスクリプトもテスト中ですが、0シェルでは成功を意味する終了状態ですが、awkではfalseを意味する条件です。 2つは非常に異なります。

シェルに結果of [ $foo ](or test $foo) は it に含まれる終了状態に対して短縮型を行い、[その後条件で評価され、 true と確認されます。次のように書くことで、awkで同じ機能を得ることができます。testfooif

awk '
    function test(exit_status) { return (exit_status==0 ? 1 : 0) }
    BEGIN{ foo=0; if ( test(foo) ) print "true"; else print "false" }
'
true

あなたははいと言いますI did run NR%2==1 and NR%2==0 and it gives me odd / even output as predicted.。 awk 1(またはゼロ以外の値)は条件付きtrueコンテキストにあるため、現在の行を印刷します0が、falseは現在の行を印刷しないためです。

関連情報