web-dev-qa-db-ja.com

シェル:バックスラッシュではなく一重引用符で文字列を引用する

文字列を一重引用符で囲むにはどうすればよいですか?

たとえば、次のことができます。

$ printf "%q\n" 'two words'
two\ words
$

出力として一重引用符(または二重引用符)を取得する方法はありますか。

$ MAGIC 'two words'
'two words'
$

一重引用符のバージョンの方がはるかに読みやすいと思います。

{ba、z} shで機能する答えを教えてください。 POSIXシェルはボーナスになります。

6
Tom Hale

仮定して:

_$ value=$'This isn\'t a \n\x1b "correct" test'
$ printf '%s\n' "$value"
This isn't a
"correct" test
_

posixquote () { printf %s\\n "$1" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/" ; }

使用する:

_$ quote "${value}"
'This isn'\''t a
"correct" test'
_

から リッチのsh posixトリック

この関数は、文字列内の"_'_"(一重引用符)のすべてのインスタンスを"_'\''_"(一重引用符、バックスラッシュ、一重引用符、一重引用符)に置き換えるだけで、最初に一重引用符を置き、文字列の終わり。一重引用符内で特別な意味を持つ唯一の文字は一重引用符自体であるため、これは完全に安全です。末尾の改行は正しく処理され、最後の単一引用符は安全文字としても機能し、コマンド置換が末尾の改行を破壊しないようにします。

_ quoted=$(quote "$var")
_

警告:上記のESC(\ 033または\ x1bまたは10進27)文字は(技術的に)引用されますが、表示されません。端末に送信されると、他の制御文字と同様に、害を及ぼす可能性さえあります。それらが$ '\ 033'、$ '\ C- ['、または$ '\ E'として視覚的に提示されている場合にのみ、明確に表示され、明確になります。

bash _printf '%s\n' "${value@Q}" $'This isn\'t a \n\E "correct" test'_

zshprintf '%s\n' ${(q)value} This\ isn\'t\ a\ $'\n'$'\033'\ \"correct\"\ test
zshprintf '%s\n' ${(qq)value} 'This isn'\''t a "correct" test'
zshprintf '%s\n' ${(qqq)value} "This isn't a \"correct\" test"
zshprintf '%s\n' ${(qqqq)value} $'This isn\'t a \n\033 "correct" test'
zshprintf '%s\n' ${(q-)value} 'This isn'\''t a "correct" test'
zshprintf '%s\n' ${(q+)value} $'This isn\'t a \n\C-[ "correct" test'

一部のzsh引用文字列に注意してください。上記のESC(\ 033または\ x1bまたは10進27)文字はすべて(技術的に)引用されていますが、表示されません。端末に送信されると、他の制御文字と同様に、害を及ぼす可能性さえあります。それらが$ '\ 033'、$ '\ C- ['、または$ '\ E'として視覚的に提示されている場合にのみ、明確に表示され、明確になります。

バッシュのマニュアル から:

_${parameter@operator}_
Q拡張は、入力として再利用できる形式で引用されたパラメーターの値である文字列です。

zshexpn manページ から:

q
バックスラッシュ付きの結果の単語でシェルに特有の引用文字。印刷できない文字または無効な文字は、_$'\NNN'_形式を使用して引用され、各オクテットは別々に引用されます。

このフラグを2回指定すると、結果の単語は一重引用符で囲まれ、3回指定すると、単語は二重引用符で囲まれます。これらの形式では、印刷できない文字や無効な文字の特別な処理は行われません。フラグが4回指定されている場合、単語は_$_が前に付いた単一引用符で囲まれます。これら3つの形式すべてで、引用が無条件に行われることに注意してください。これにより、結果の文字列がシェルによって解釈される方法が変更されない場合でもです。

_q-_が指定されている場合(単一のqのみが表示される場合があります)、特殊文字を保護する必要がある場合にのみ文字列を引用する最小の形式の単一引用符が使用されます。通常、このフォームは最も読みやすい出力を提供します。

_q+_が指定されている場合、最小形式の拡張形式が使用され、これにより、印刷できない文字が_$'...'_を使用してレンダリングされます。この引用は、タイプセットファミリのコマンドによる値の出力で使用される引用と似ています。

5
Isaac

Zshには パラメータ展開 に適用できる引用オプションがたくさんあります:

q

結果の単語でシェルに特有の文字をバックスラッシュで引用します。印刷できない文字または無効な文字は、$'\NNN'形式を使用して引用され、各オクテットは個別に引用されます。

このフラグを2回指定すると、結果の単語は一重引用符で囲まれ、3回指定すると、単語は二重引用符で囲まれます。これらの形式では、印刷できない文字や無効な文字の特別な処理は行われません。フラグが4回指定される場合、単語は$が前に付いた単一引用符で囲まれます。これらの3つの形式すべてで、引用が無条件で行われることに注意してください。これにより、結果の文字列がシェルによって解釈される方法が変更されない場合でも同様です。

q-が指定されている場合(単一のqのみが表示される場合があります)、特殊文字を保護する必要がある場合にのみ文字列を引用する最小形式の単一引用符が使用されます。通常、このフォームは最も読みやすい出力を提供します。

q+が指定されている場合、$'...'を使用して印刷できない文字をレンダリングする拡張形式の最小引用が使用されます。この引用は、タイプセットファミリのコマンドによる値の出力で使用される引用に似ています。

したがって、次のような関数:

MAGIC () {
    printf "%s\n" "${(q+)@}"
}

次のような出力が得られます:

$ MAGIC 'two words'
'two words'
$ MAGIC 'two words "'
'two words "'
$ MAGIC 'two '"'"'words'
'two '\''words'
4
muru