awk内で単一引用符をエスケープする方法


110

次のことをしたい

awk 'BEGIN {FS=" ";} {printf "'%s' ", $1}'

しかし、この方法で単一引用符をエスケープしても機能しません

awk 'BEGIN {FS=" ";} {printf "\'%s\' ", $1}'

これを行う方法?手伝ってくれてありがとう。


多くの言語は、2つを並べて引用をエスケープします。試してみてください。
joshuahealy

awk 'BEGIN {FS = "";} {printf "' '%s' '"、$ 1}'を試しましたが、単一引用符が印刷されませんでした。

このページでは、単一引用符で囲まれた文字列に単一引用符を含めることは不可能であると述べています。多分あなたは二重引用符に変換する必要があるでしょう。
joshuahealy

2
不可能ですが、単一引用符で囲まれた2つの隣接するシェル文字列が1つのパラメーターに結合されます。また、空白以外の文字で接着された単一引用符で囲まれた2つのシェル文字列も、1つの大きなグロブに接着されます:'abc'd'ef'is abcdef:literal plus dplus literal。d引用符の外で、あなたはそれを置き換えることができdて、それ\'メイクへ'abc'\''ef'と評価されましたabc'ef
Kaz

回答:


160

これはおそらくあなたが探しているものです:

awk 'BEGIN {FS=" ";} {printf "'\''%s'\'' ", $1}'

つまり'\''、開口部を閉じ、'リテラル'をエスケープして出力し、最後に'もう一度開きます。


47
awkとは関係ありません。'文字は、開口部の閉じ'シェル文字列リテラルを。シェルリテラルは、このためのバックスラッシュエスケープをサポートしていません。シーケンスは、'\''トリックを行います。それは、単一引用符のリテラルを閉じて(エスケープ使用して引用符文字を指定された単一引用符リテラルの外をサポートする)し、新しい単一引用符リテラル再オープンします。これは、単一引用符を取得するための4文字のエスケープシーケンスと考えることができます。:)
Kaz

2
@Steve:非常に役立つ回答をありがとうございました。あなたは私に多くの頭痛の種を救った!
John Slegers 14年

4
@syntaxerror呼び出すための引数を準備するために使用する引用符awkは、コマンドラインの作成に使用するコマンドインタープリターの問題です。'{printf $2}'以下のためのいくつかの議論になってますexecve、それはただの単一引用符なしでnullで終了C文字列のように見えるシステムコールまたは類似の、。Awkが引用符を見ることはなく、sedを見ることもありません。実際には二重引用符を使用できますが、二重引用符はシェルのの展開を妨げないため、$2円記号をリテラルにするために円記号でエスケープする必要があります"{printf \$2}"
Kaz

4
@syntaxerrorカスタムでは、インラインawkスクリプトは通常、単一引用符でエスケープされます。これは、awk構文には、二重引用符付き文字列リテラルやドル記号で示される番号付きフィールドなど、シェルに特有の字句要素が含まれることが多いためです。sed正規表現(またはその他)にシェル構文が含まれている場合は、注意する必要もあります。sed -e "s/$FOO/$BAR/"リテラルテキスト$FOOをに置き換えることが目的の場合は機能しません$BAR。最も簡単な方法はでしょうsed -e 's/$FOO/$BAR/
Kaz

1
@syntaxerror awkプログラムを二重引用符で囲むと、などの多くのエスケープに遭遇しますawk "{ print \"abc\", \$1 }"。二重引用符がawkプログラムに表示されるときは常に、シェル引用符を閉じないようにエスケープする必要があります。そして、これを比較しますawk '{print "\\"}'(バックスラッシュを印刷する)、それは二重引用符で必要なものを対:awk "BEGIN {print \"\\\\\" }"、ふう!両方の引用符と両方のバックスラッシュをエスケープする必要があります。シェルがに変換さ\\ れる\ ため\\\\ 、エンコードする必要があり\\ ます。
Kaz

76

一重引用符は、 \x27

のように

awk 'BEGIN {FS=" ";} {printf "\x27%s\x27 ", $1}'

ソース


16
+1、ただし追加が必要:\x27拡張機能です。POSIX Awkはのみを認識し\047ます。(\478進数が続かない場合も問題ありません。)
hemflit 2013年

1
その後に別の番号がある場合、どのように\ x27を終了しますか?
Jason Axelson 2013

1
ジェイソン、2つの文字列リテラルを連結します: "AAA \ x27" "1"。または、8進数を使用します。
hemflit 2014年

9
常に\04716 進数()ではなく8進数()の\x27エスケープコードを使用してください-awk.freeshell.org/PrintASingleQuoteを参照してください。
Ed Morton

35

別のオプションは、単一引用符をawk変数として渡すことです

awk -v q=\' 'BEGIN {FS=" ";} {printf "%s%s%s ", q, $1, q}'

文字列を連結した簡単な例:

# Prints 'test me', *including* the single quotes.
$ awk -v q=\' '{print q $0 q }' <<<'test me'
'test me'

5
これは、特に多くの引用符を使用する必要がある場合は、明確で簡潔です。
Peter Gluck

18
awk 'BEGIN {FS=" "} {printf "\047%s\047 ", $1}'

1
それ\047が単一引用符文字の8進エスケープシーケンスであることを覚えている限り、この代替手段が最も読みやすいと思います。
Anthony Geoghegan

4

小さなスクリプトの場合、読みやすくするためのオプションの方法は、次のような変数を使用することです。

awk -v fmt="'%s'\n" '{printf fmt, $1}'

出力で一重引用符文字を何度も生成する必要があり、\ 047が完全に判読不能にしていた場合に便利でした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.