誰かが以下のコマンドで何が起こっているのか説明できますかawk
?エラーがないとnotme
印刷されないのはなぜですか? 構文エラーが発生しないのはなぜですか?閉じ括弧の場合、引用...}
符で閉じる必要がありますか...}'
?
$ awk '{print "me "$0 '"notme"} <<<"printme"
me printme
それではこれを試してみましょう。
$ awk '{print "me "$0 '"\"$(date)"\"} <<<"printme-at "
me printme-at Wed Apr 11 16:41:34 DST 2018
または
awk '{print '"\"$(date)\""} <<<"run"
Wed Apr 11 16:56:38 DST 2018
その結果、これはシェルコマンド置換を使用してすべての操作を実行できることを意味します。
これはバグですか?それとも、私が見つけることができない特別な状態かもしれません。
答え1
初めて
$ awk '{print "me "$0 '"notme"} <<<"printme"
ここで何が起こるかは次のとおりです。
- 一重引用符で囲まれた部分は
awk
そのまま渡されます。 - 次の部分は
"notme"}
シェルによって解析され、結果のawk
文字列に渡されます。notme}
awk
あなたはこれを見ることができます:{print "me "$0 notme}
awk
変数には値がないため、notme
次のような結果が得られます。
第二に
$ awk '{print "me "$0 '"\"$(date)"\"} <<<"printme-at " me printme-at Wed Apr 11 16:41:34 DST 2018
awk
私は値を渡すために変数を使って次のように書くことを好みます$(date)
。
awk -v date="$(date)" '{print "me "$0 date}' <<<"printme-at "
me printme-at Wed Apr 11 13:43:31 BST 2018
あなたのバージョンに構文エラーがない理由を尋ねました。それを分析しましょう:
# typed at the shell
awk '{print "me "$0 '"\"$(date)"\"} <<<"printme-at "
# prepared for awk
awk '{print "me "$0 "Wed Apr 11 16:41:34 DST 2018"}' <<<"printme-at "
# seen by awk
{print "me "$0 "Wed Apr 11 16:41:34 DST 2018"}
二重引用符で囲まれた文字列は、近くに到達"\"$(date)\""
する前にシェルによって解析され、リテラル文字列(二重引用符を含む)のようにawk
(シェルによって)評価されます。"Wed Apr 11 13:43:31 BST 2018"
書いた内容が有効なので文法エラーが必要な理由がわかりません。読み方は少し複雑ですが。
答え2
awk
一重引用符は、シェル内のプログラムを区切る文字列を終了します。awk
それ自体では決して見ることができません。その後、プログラムの最初の部分をコマンド置換によって提供される追加の文字列とシェルの静的文字列と関連付けることができます。これはすべてawk
通話前に発生します。
もちろん、コマンド置換を使用して後でコードで読み込まれる文字列を変更できますが、awk
実際にはコードを読みやすくすることはできず、シェルの引用規則、トークン化などにかなり脆弱です。
awk
一般的な方法で変数を設定することをお勧めします。
awk -v thedate="$(date)" '{ print $0, thedate }' <<<"something"