awkの最初の文に必要な変数がありますか?

awkの最初の文に必要な変数がありますか?

今日はawkに苦労しています。私がこれをしようとすると:

df|awk '{print $2; $some=$2; print $some}'

期待どおりに動作し、ディスクサイズが2倍になりますが、そうすると次のようになります。

df|awk '{$some=$2; print $some}'

空行のみが表示されます。なぜこれが起こるのですか?私が理解した内容に問題がある可能性がありますが、なぜ後続のフィールドが機能するために1つのフィールドを使用する必要がありますか?私もこれを試しました:

df|awk '{print "hello"; $some=$2; print $some}'

私はそれぞれ改行で区切られた複数の「hello」を取得します。 $some=$2 はどこにありませんか?

私のdfコマンド出力:

Filesystem     1K-blocks     Used Available Use% Mounted on
/dev/sda5       38448788 32098732   4396932  88% /
udev             1914564        4   1914560   1% /dev
tmpfs             768744      984    767760   1% /run

答え1

$前に - 記号を使用しないでくださいsome。最初のコマンドが $2印刷され、その後$some=$2に変換され(一部の実装ではすべてではなくに変換され、エラーメッセージが表示されます)、Record()をforに置き換えて印刷します。これは次のようなことを意味します。$0=$2someawksome""0$0$2$some$0

df|awk '{print $2; $0=$2; print $0}'

そして

df|awk '{$0=$2; print $0}'

あなたがしたいことは次のとおりです。

df|awk '{print $2; some=$2; print some}'

答え2

予想した結果を得ました。最初のコマンドは各項目を2回印刷します。 2番目のコマンドはそれを一度印刷します。

これはやや異なる方法です。 "some" は定義されていないため、デフォルトは 0 です。したがって、 $some は $0 で、これは行全体を表します。したがって、デフォルトでは$ 2を使用するときは、その行を$ 2の内容に置き換えます。$some=$2

この結果と比較してください。

johan@computer:~$ df|awk '{$some=$2; print}'
1K-blocks
30827524
4041028
1621692
5120
4054228
102400
4054228
60555340
209548784

出力やその他の結果が出ない理由:少なくとも一部のシステムでは、初期化されていない変数を使用する動作が定義されていない可能性があると予想しています。

Solarisでは、/usr/xpg4/bin/awkにインストールされているPOSIX互換バージョンだけでなく、「標準」awkにもアクセスできます。これらの両方について同じ結果を生成します。

前にprint "hello"を追加するのか、最後のコマンドを(print $ someの代わりに) "print"に置き換えるのかによって異なる結果が生成されます。

しかし、彼らはすべて空白の代わりに何かを印刷します。私はまだこの効果を再現するバージョンを見つけることができませんでした。

だから私は、これが初期化されていない変数を使用して発生する一種の未定義の動作であると予想しました。可能な列範囲の終わりをはるかに超える列に値を割り当てています。入力ストリームから。 $some は、"some" 値で識別される列を表します。

変数としては「some」のみを使用してください。

df | awk '{print "hello";some=$2; print some}'

答え3

私の考えでこれが起こるのは、Ubuntuが標準のGNU移植を使用せずに標準のUnixで動作する多くのコードを破るmawkという別のものを使用するためだと思います。

これを参照してください協会同様の議論をしてください。

関連情報