二重引用符なしまたは二重引用符付きで使用する場合、bashはバックスラッシュを同じように扱うといつも思っていましたが、間違っていました。
[user@linux ~]$ echo "foo \ "
foo \
[user@linux ~]$ echo foo \ # Space after \
foo
したがって、二重引用符を使用すると、バックスラッシュは常に出力されると思いましたが、次のようになります。
[user@linux ~]$ echo "foo \" "
foo "
[user@linux ~]$ echo "foo \\ "
foo \
最初のコード行にバックスラッシュが表示されるのはなぜですか?
セクション .1.2.3二重引用符GNU Bashマニュアル の説明:
バックスラッシュは、 '_
$
_'、 '_`
_'、 '_"
_'、 '_\
_'、またはnewline
のいずれかの文字が続く場合にのみ、特別な意味を保持します。 。二重引用符内では、これらの文字のいずれかが後に続くバックスラッシュが削除されます。特別な意味のない文字の前のバックスラッシュは変更されません。二重引用符は、バックスラッシュを前に付けることにより、二重引用符で囲むことができます。有効にすると、二重引用符で囲まれた「_!
_」がバックスラッシュを使用してエスケープされない限り、履歴の展開が実行されます。 「_!
_」の前のバックスラッシュは削除されません。
したがって、二重引用符内の_\
_は、単一引用符内の_\
_および引用符外の_\
_の両方とは異なる方法で処理されます。二重引用符で特別な意味を持つ可能性がある文字を文字どおりに処理する位置にある場合を除いて、文字どおりに処理されます。
_\'
_、_\?
_および_\*
_であるため、_'
_、_?
_、_*
_などのシーケンスは文字どおりに扱われ、バックスラッシュは削除されません。二重引用符で囲まれている場合、すでに特別な意味はありません。
バックスラッシュの解釈はコンテキストによって異なります。
二重引用符内(最初の例):
The backslash retains its special meaning only when followed
by one of the following characters: $, `, ", \, or <newline>.
引用符なし(2番目の例):
A non-quoted backslash (\) is the escape character. It
preserves the literal value of the next character that
follows, with the exception of <newline>. If a \<newline>
pair appears, and the backslash is not itself quoted, the
\<newline> is treated as a line continuation (that is, it is
removed from the input stream and effectively ignored).
構成要素$'....'
を使用します。引用符の内部では、Cとほぼ同じように、標準のバックスペース文字を使用できます。 \n
、\t
など.
バッククォートの使用:
When the old-style backquote form of substitution is used,
backslash retains its literal meaning except when followed by
$, `, or \.
引用のソース:bashマニュアル
ここに「理解のために複雑な」例があります。うまくいけば、クォートとバックスラッシュを理解しようとしている他の人にとって役立つでしょう。
この例では、パターンを3回繰り返します。
>~# echo 'ABC\n\t'
ABC\n\t
一重引用符を使用すると、かなり簡単です。
>~# echo 'ABC\n\t' | sed -e 's#ABC\\n\\t#ABC\\n\\tABC\\n\\tABC\\n\\t#'
↑ ↑ ↑ ↑ ↑ ↑ ↑
# These backslashes escaped by sed
ABC\n\tABC\n\tABC\n\t
二重引用符を使用してこれを行う方法は次のとおりです(ここでも、理解のためだけに複雑です)。
>~# echo 'ABC\n\t' | sed -e "s#ABC\\\n\\\t#$(printf '%0.sABC\\\\n\\\\t' $(seq 1 3))#"
↑ ↑ ↑ ↑ ↑ ↑
# These backslashes are removed in double quotes. Showing intermediate stage:
>~# echo 'ABC\n\t' | sed -e "s#ABC\\n\\t#$(printf '%0.sABC\\n\\t' $(seq 1 3))#"
# Expanding printf results in:
>~# echo 'ABC\n\t' | sed -e 's#ABC\\n\\t#ABC\\n\\tABC\\n\\tABC\\n\\t#'
ABC\n\tABC\n\tABC\n\t
試してみて、引用符とバックスラッシュをマスターするには、printfの前後の一重引用符を二重引用符に置き換えます。