web-dev-qa-db-ja.com

`... | awk '$ 1 = $ 1'`余分なスペースを削除しますか?

私の理解から、$1は最初のフィールドです。しかし、奇妙なことに、awk '$1=$1'は余分なスペースを省略します。

$ echo "$string"
foo    foo bar               bar

$ echo "$string" | awk '$1=$1'
foo foo bar bar

なぜこうなった?

16
annahri

フィールド変数に値を割り当てるとき、すなわち。 $ 1の値はフィールド$ 1に割り当てられ、awkは実際にそれらをデフォルトのフィールド区切り文字(またはOFS)スペースと連結することによって$ 0を再構築します。

次のシナリオでも同じケースになります...

echo -e "foo foo\tbar\t\tbar" | awk '$1=$1'
foo foo bar bar

echo -e "foo foo\tbar\t\tbar" | awk -v OFS=',' '$1=$1'
foo,foo,bar,bar

echo -e "foo foo\tbar\t\tbar" | awk '$3=1'
foo foo 1 bar

GNU AWKの場合、この動作は次のとおりです。
https://www.gnu.org/software/gawk/manual/html_node/Changing-Fields.html

$ 1 = $ 1#強制的にレコードを再構成する

18
Siva
echo "$string" | awk '$1=$1'

aWKが$1=$1を評価するようにします。これにより、フィールドがそれ自体に割り当てられ、$0を再評価するという副作用があります。次に、AWKは式の値を考慮します。これはゼロではなく空でもないため、$0を出力するというデフォルトのアクションを実行します。

余分なスペースは、AWKが$0を再評価するときに削除されます。これは、区切り文字としてOFSを使用してすべてのフィールドを連結することによって行われます。これは、デフォルトでは1つのスペースです。 AWKがレコードを解析するとき、$0にはレコード全体がそのまま含まれ、$1から$NFには区切り記号なしのフィールドが含まれます。フィールドが割り当てられると、$0がフィールド値から再構築されます。

この例でAWKが何かを出力するかどうかは、入力に依存します。

echo "0      0" | awk '$1=$1'

何も出力されません。

12
Stephen Kitt