为什么需要 2 个反斜杠来转义 vim -c 参数中的反斜杠?

Why 2 backslashes are needed to escape a backslash in vim -c argument?

在 Windows 10 中,我在 Git bash 1.9.5,

中使用了以下命令
$ vim -c "%s/^/\=line(".").'. '/g" -c "%s/\//\/g" -c "%y+" -c "wq" ~/Desktop/sample.txt

为了,

  1. -c "%s/^/\=line(".").'. '/g": 在每行前添加一个数字序列。
  2. -c "%s/\//\/g": 用反斜杠替换所有斜杠。
  3. -c "%y+" -c "wq": 将所有文本复制到剪贴板,保存并退出 Vim.

2外,一切正常,Vim似乎无法正确处理-c "%s/\//\/g"参数。 None 个斜杠被替换,并且在每行的第一个 / 之后插入一个 g。例如,

Sample.txt before

A/P/A/T/H
B/P/A/T/H

Sample.txt after

A/gP/A/T/H
B/gP/A/T/H

但是,如果我在 vim 中执行 :%s/\//\/g,它会按我的预期工作。

此外,这些我都试过了,

所以,我想知道这是 -c 参数的限制或已知问题,还是我在某处出错了?

编辑:我只是偶然发现 -c "%s/\//\\/g" 按预期工作。
那么谁能解释一下为什么需要另一个 \ 来逃避 \?

在 Vim 中,当使用正则表达式时,反斜杠用于转义字符,因此不能单独使用它来表示文字反斜杠。为此,您必须使用转义反斜杠转义文字反斜杠:

:%s/\//\/g

因此,无论如何您都以 两个 反斜杠开头:转义反斜杠和原义反斜杠。这就是 Vim 所期望的。

在你的shell中,反斜杠也有特殊的含义。当在双引号内时,两个连续的反斜杠“折叠”成一个反斜杠,所以当你认为你在告诉 Vim 做:

:%s/\//\/g

与:

-c "%s/\//\/g"

实际收到的是:

%s/\//\/g

这意味着:“用转义斜杠(简单的斜杠)后跟字母 g 替换每个斜杠”。不完全是你的想法。

要确保 Vim 确实收到正确的命令,您需要添加 third 反斜杠:

-c "%s/\//\\/g"

两个反斜杠折叠成一个,另一个保持原样,所以您最终得到 两个 个反斜杠,这正是 Vim 所期望的:

%s/\//\/g

另一个更好的方法是使用单引号,其中反斜杠始终是文字,而不是双引号:

-c '%s/\//\/g'

From this page about shell quoting,强调我的:

The backslash retains its meaning only when followed by dollar, backtick, double quote, backslash or newline. Within double quotes, the backslashes are removed from the input stream when followed by one of these characters.