こんにちは、私は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番目の行などが印刷されます。
NR
0から世紀を始めると状況が変わります。
答え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で同じ機能を得ることができます。test
foo
if
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は現在の行を印刷しないためです。