2017-12-06 7 views
1

私は変数に格納された文字列のグループから文字列を抽出しようとしている、bashで、foo言います私はシングルと二重引用符でawkを包んだとき:ダブルとシングルクオートは

$ echo $foo | awk '{print $2}' 
$ foobar 

$ echo $foo | awk "{print $2}" 
$ I foobar you 

を誰が、なぜ'を教えてもらえと"awkを包むときに異なる結果を引き起こしますか?

+0

シェルクォートルールを読んでおく必要があります。彼らはあなたの質問に答えて、さらに 'echo $ foobar'が' echo "$ foobar" 'と書かれているはずの悪いコードである理由をあなたに伝えます。非常に明確な目的を念頭に置いていない限り、シェル変数を引用符で囲まずに引用符で囲み、すべての意味、副作用および警告を十分に理解してください。 –

答えて

3

二重引用符を使用すると、シェルはawkに渡す前に位置パラメータまたは変数として展開しようとします。あなたの場合は、$1を展開しようとしますが、値が見つからないので、展開結果はになりません。となり、行全体を印刷するためにawkでデフォルトの印刷アクションが得られます。

我々はawkのコマンドを引用選抜理由は、我々はプレーンな文字列をしたいということで、デフォルトのスペース区切り文字で最初のフィールドとして$1を理解awkコマンド自体(によって処理する前に任意の手段によって、シェルによって改ざん/変更されませんシェル引用規則による)

+0

これはawkと全く関係がないことを100%明確にするだけです。 awkは、シェルが渡すスクリプトを単純に解釈します。たとえば、 '$ 1'を展開しようとしていると言ったときには、awkではなくシェルであることが分かります。シェルは、引用符を解釈してawkに渡すものを計算し、awkやsedなどのコマンドにスクリプトを渡しても、同じ動作をします。 –

1

  • 単一引用符(」「)開閉引用符の間のすべてを保護します。シェルは引用されたテキストの解釈を何もせず、それを逐語的にコマンドに渡します。
    $ echo $foo | awk '{print $2}'
    $ foobar

  • 二重引用符(「「)の開閉の間にほとんどのものを守る:それはアクションとしてawkのことですよう

    あなたのコードのように渡さ{$ 2印刷}引用符。シェルは、引用符で囲まれたテキストに対して少なくとも変数とコマンド置換を行います。異なるシェルは、二重引用符で囲まれたテキストに対して別の種類の処理を行うことがあります。二重引用符で囲まれたテキスト内の特定の文字はシェルによって処理されるため、テキスト内でエスケープする必要があります。文字列 '$'、 '' '、' \ '、' ''に注意してください。プログラムに文字通り渡す場合は、二重引用符で囲まれたテキストの前にバックスラッシュを付ける必要があります。

    だからように、第2 COLの値を取得するために$をエスケープする必要があります。それ以外の場合はawkがあなたの場合のように、全体のラインを印刷するデフォルトのアクションをやっている
    $ echo $foo | awk "{print \$2}"
    $ foobar

  • 完全にシェル変数を引用するベストプラクティスに関して@Ed Mortanと合意しました。ブリークの引用はデフォルトですが、誤っている場合は...。
    $ echo "$foo" with double quotes
    $ I foobar you

    $ echo ‘$foo’ with single quotes
    $ $foo

  • ルールがシェルに固有の引用、覚えておいてください。上記の規則は、POSIXに準拠したBourneスタイルのシェル(Bash、GNU Bourne-Againシェルなど)にのみ適用されます。それは、awk、sed、grepなどとは関係ありません。