私はいつもbashが二重引用符なしで、または二重引用符で使用するときにバックスラッシュを同じように扱うと思いましたが、間違っていました。
[user@linux ~]$ echo "foo \ "
foo \
[user@linux ~]$ echo foo \ # Space after \
foo
だから、二重引用符を使用すると、バックスラッシュが常に印刷されると思いましたが、次のようになります。
[user@linux ~]$ echo "foo \" "
foo "
[user@linux ~]$ echo "foo \\ "
foo \
コードの最初の行にバックスラッシュが表示されるのはなぜですか?
答え1
部分3.1.2.3二重引用符~のGNU バッシュマニュアル説明する:
$
バックスラッシュは、''、'`
'、'"
'、'\
'、または文字のいずれかが後に続く場合にのみ特別な意味を維持しますnewline
。二重引用符内では、これらの文字の1つに続くバックスラッシュが削除されます。特別な意味を持たない先行バックスラッシュ文字は変更されません。二重引用符の前にバックスラッシュを追加すると、二重引用符の中に二重引用符を入れることができます。有効にすると、!
二重引用符内に表示される""がバックスラッシュにエスケープされていない限り、記録拡張が行われます。 「」の前のバックスラッシュは!
削除されません。
したがって、\
二重引用符の処理は、一重引用\
符と外部引用符の\
処理とは異なります。文字を文字通り処理する位置にない限り、文字通り処理されます。この場合、その文字は二重引用符内で特別な意味を持つことができます。
\'
\?
、、などのシーケンスは文字通り\*
処理され、後でバックスラッシュは削除されず、二重'
引用符で囲まれている場合は特に意味がありません。?
*
答え2
バックスラッシュは状況によって異なるように解釈されます。
二重引用符内(最初の例):
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
これは「理解のために仕事を複雑にすること」の例です。他の人が引用符とバックスラッシュを理解するのに役立つことを願っています。
この例では、パターンを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の周りの一重引用符を二重引用符に置き換えます。