在 sed 表达式中转义反冲和双引号(由双引号包围)

pi-*_*tar 2 bash sed shell-script quoting text-formatting

$ echo 'output: " ' | sed "s/\"/\"/"
output: "

$ echo 'output: " ' | sed "s/\"/\\\"/"
output: "

$ echo 'output: " ' | sed "s/\"/\\\\\"/"
output: \"
Run Code Online (Sandbox Code Playgroud)

我想了解第一个和第二个示例中发生了什么。我的理解是,因为我使用双引号的sed表达,\"是interpreded作为"\\被解释为\。如果是这样,那么为什么我的第二个输出是"而不是\"

我知道我可以在sedas 中使用单引号's/"/\"/',但它不能正常工作并替换"".

我真的很好奇为什么双引号会观察到这种行为。

  • GNU bash,版本 5.1.4(1)-release (x86_64-pc-linux-gnu)
  • sed (GNU sed) 4.8

Qua*_*odo 5

外壳规范中

2.2.3 双引号

双引号 ( "" ) 中的字符应保留双引号内所有字符的字面值,但反引号、美元符号和反斜杠字符除外,如下所示:

(……)

反斜杠只有在被认为是特殊的情况下后跟以下字符之一时才应保留其作为转义字符的特殊含义:
$ ` " \ <newline>

所以,

案件 在 shell 之前(你看到的) 在 shell 之后(Sed 得到什么)
1 "s/\"/\"/" s/"/"/
2 "s/\"/\\\"/" s/"/\"/
3 "s/\"/\\\\\"/" s/"/\\"/

Sed 的规范中s命令:

未转义反斜杠后跟除“&”、反斜杠、数字、换行符或用于此命令的定界符以外的任何字符的含义未指定。

因此,在情况 2 中,输出是未指定的(即,Sed 实现可以随意解释这种情况)。GNU Sed 自由地提供了几个特殊字符,其中\r用于回车、\n换行等(请参阅手册中的完整列表)。\"不是其中之一,它选择简单地删除反斜杠。因此,情况 2 就等同于 GNU Sed 中的情况 1。