私は学び始め、awk
次のコマンドを実行したときに何かに会いました。
$ echo ":a:b:c:" | awk '$1=$1' FS=":" OFS="$"
$ echo "a:b:c:" | awk '$1=$1' FS=":" OFS="$"
a$b$c$
$a$b$c$
最初のコマンドは何も返しませんが、2番目のコマンドと同様に返したいと思います。通常、フィールド区切り文字が行の先頭にある場合は何も印刷しません。なぜこれですか?
答え1
スクリプトでは、印刷はデフォルトのジョブとして実行されます。これは、パターンによる割り当てのawk
「副作用」の評価に依存します。$1=$1
最初のケースでは、最初の区切り文字の前には空のフィールドがあり、空の文字列$1
も同様にFALSEと評価されます。 2番目の場合は、TRUEと評価され、デフォルトの印刷ジョブをトリガーする空では$1
ない文字列です。a
答え2
awkにレコードを印刷させるには、最初のフィールドの実際の値に依存します。空の文字列の真理値は偽なので、awkは値を割り当てる以外は何もしません。1
最初のフィールドをチェックとして使用するのではなく、明示的に印刷します(または常にtrueである他の条件(たとえば)を使用)。
echo ":a:b:c:" | awk '{$1=$1; print}' FS=":" OFS="$"
答え3
- 非常に具体的な要件がある場合を除いて(たとえば、存在する文字を削除しようとした場合、成功時にいくつかのタスクを実行したい場合など)、タスクの結果を条件として評価しないでください。
- 変数を使用するコードを表示する前に設定されている変数を見ると、コードを読みやすくするため、ファイルリストに変数の割り当てをリストしないでください。後ろに非常に特定の要件(ファイル間の値の変更など)がない場合は、
-v
awkを呼び出す前または割り当てを使用してリストします。BEGIN
ENVIRON[]
https://stackoverflow.com/q/19075671/1745001)。 - 二重引用符を使用したり、引用符を使用したりする必要がない非常に特別な要求がない限り、シェルのすべての文字列(スクリプトを含む)の周りに一重引用符を使用してください(参照https://mywiki.wooledge.org/Quotes)。
したがって、スクリプトはawk -F':' -v OFS='$' '{$1=$1}1'
。