`... | awk '$1=$1'' ` 余分なスペースを削除するには?

`... | awk '$1=$1'' ` 余分なスペースを削除するには?

私の理解は$1最初のフィールドです。ところで、奇妙に余分なawk '$1=$1'空白が省略されます。

$ echo "$string"
foo    foo bar               bar

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

なぜこれが起こるのですか?

答え1

つまり、フィールド変数に値を割り当てるときです。値は$1フィールドに割り当てられ、$1awkは実際にそれをデフォルトのフィールド$0区切り文字(またはOFSスペース)に関連付けて再構成します。

次のシナリオでも同じ状況が発生する可能性があります。

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 # 強制記録の再編成

答え2

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

AWKに$1=$1フィールドをそれ自体に割り当てる評価を実行させ、$0AWKは式の値を考慮し、ゼロでもNULLでもないため、基本的な操作を実行します。印刷$0

AWKが再計算すると、余分なスペースが削除されます。デフォルトでは、空白の$0区切り文字ですべてのフィールドを連結してこれを行います。OFSAWKがレコードを解析すると、レコード全体が$0そのまま含まれ、フィールドが$1含まれる$NFと(区切りなし)、$0フィールド値から再編成されます。

この例では、AWKが出力されるかどうかは入力によって異なります。

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

何も出力されません。$1=$1最初のフィールドの内容を評価します0。これはAWKでは「偽」の結果であるため、何も起こらず、出力も提供されません。これを回避するには、$1=$1アクションを実行し、AWKがすべての場合に現在のレコードを印刷するようにしてください。

| awk '{$1=$1}1'

1AWKに常にデフォルトのジョブを実行させます。

関連情報