为什么`echo -e "\\\SOME_TEXT"` 只显示一个反斜杠?

Moh*_*din 21 linux bash escape-characters echo escaping

有人能解释一下 Linux shell 中字符转义的幕后情况吗?我尝试了以下方法并在谷歌上搜索了很多,但没有成功理解正在发生的事情(以及如何发生):

root@sv01:~# echo -e "\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\\\ Hello!"
\\\ Hello!
root@sv01:~# echo -e "\n Hello!"

 Hello!
root@sv01:~# echo -e "\\n Hello!"

 Hello!
root@sv01:~# echo -e "\\\n Hello!"
\n Hello!
Run Code Online (Sandbox Code Playgroud)

我完全迷失在那里,例如,为什么三个反斜杠只给出一个反斜杠?我希望:前两个将被转义为一个,第三个将找不到任何可以转义的内容,因此它仍然是一个斜线(第一个实验中的行),但正在发生的事情是第三个只是消失了。
为什么我从四个中得到一个反斜杠\\\\ Hello我希望每一对都会给一个反斜杠 - > 两个反斜杠。

为什么在最后一种情况下我需要三个反斜杠才能转义 \n ?在逃跑的背景下发生了什么?它与\\n案例有何不同?

我感谢对前几行中发生的事情的任何解释。

Kam*_*ski 31

这是因为bashecho -e结合。从man 1 bash

未加引号的反斜杠 ( \) 是转义字符。它保留了下一个字符的字面值,除了<newline>. […]

双引号中的字符保留引号内所有字符的字面值,但$, `, \, [...]除外反斜杠仅在后跟以下字符之一时保留其特殊含义:$, `, ", \, or <newline>

重点是:双引号反斜杠并不总是特别的。

通常有各种实现echo,它是内置的bash;这里重要的是这种行为:

如果-e有效,则识别以下序列:
\\
反斜杠
[…]
\n
换行

现在我们可以解码:

  1. echo -e "\ Hello!"– 没什么特别的bash,没什么特别的echo\停留。
  2. echo -e "\\ Hello!"– 第一个\告诉要按字面意思bash对待第二个\echo获取\ Hello!和操作如上。
  3. echo -e "\\\ Hello!"– 第一个\告诉要按字面意思bash对待第二个\echo获取\\ Hello!和(因为-e)它识别\\\
  4. echo -e "\\\\ Hello!"– 第一个\告诉要按字面意思bash对待第二个\;第三个和第四个一样;echo获取\\ Hello!和(因为-e)它识别\\\
  5. echo -e "\\\\\ Hello!"– 第一个\告诉要按字面意思bash对待第二个\;第三个和第四个一样;最后一个并不特别;echo获取\\\ Hello!并且(因为-e)它将初始识别\\\,最后\保持不变。

等等。如您所见,最多四个连续的反斜杠给出一个结果。这就是为什么你需要(至少)九个才能得到三个。9=4+4+1。

现在\n

  1. echo -e "\n Hello!"– 没有什么特别之处bash,echo 获得相同的字符串并且(因为-e)它解释\n为换行符。
  2. echo -e "\\n Hello!"bash解释\\\echo得到\n Hello!,结果和上面一样。
  3. echo -e "\\\n Hello!"bash将首字母解释\\\; echo获取\\n Hello!和(因为-e)它解释\\\需要打印的文字。

使用'而不是"(由于不同的bash行为)或不使用-e(不同的echo行为),结果会有所不同。

  • @MohammedNoureldin `sed` 将遵循相同的基本原则:bash 将根据其规则解释命令行,解析(并可能删除)引号和转义符。结果被传递给`sed`,它根据*它的*转义规则解释它。顺便说一句,您可以通过在 `bash` 中使用单引号字符串来简化它,因为它没有(通过 bash)完成任何转义解释——bash 删除了单引号,并将其中的内容直接传递给命令. (3认同)
  • @MohammedNoureldin 是的,有两个步骤。您最初的问题很好,我们不要让它与`sed` 变得过于复杂。不过,您可能会问另一个问题(仅关于“sed”),请先进行自己的研究。 (2认同)