转义文字点如何为 sed 工作

How does escaping a literal dot work for sed

下面的sed命令

echo '.' | sed "s/\./foo/"
正如预期的那样,

. 替换为 foo。但是,如果我们在上述命令中转义非字母数字 .

echo '.' | sed "s/\\./foo/"

几乎不打印 .,而 foo 是预期的。 sed 应该按字面意思匹配字符 .,但事实并非如此。我不明白点是怎么回事。我相信我应该在 bash 中的每个非字母数字字符前简单地放置一个反斜杠,如果一个字符串是双引号的话。点是非字母数字字符,那么转义它有什么问题,为什么会产生不同的结果?

在你的第二个中,. 仍然是一个文字点,但正则表达式只用 \. 替换了双字符序列(不是 . 本身) =14=]:

$ echo '=\.=' | sed "s/\\./foo/"
=foo=

这是因为反斜杠在 bash 双引号 " 转义中的工作方式。

echo "\"
\
echo "\."
\.
echo "s/\./foo/"
s/\./foo/
echo "s/\\./foo/"
s/\./foo/

来自man bash

Within double quotes, the backslash retains its special meaning only when
followed by one of the following characters: $, `, ", \,or <newline>.

所以在第一种情况下,sed 获取 s/\./foo/ 并将其解释为 "replace a dot with foo"。在第二种情况下,sed 得到 s/\./foo/ 并将其解释为“用 foo 替换反斜杠和另一个字符。

在这种情况下你最好使用单引号转义:

echo 's/./foo/'
s/./foo/
echo 's/\./foo/'
s/\./foo/

这可能是您想要的。