s///
我正在使用 CentOS,并且正在编辑器中阅读有关替换命令的内容vi
。我想测试一些我看到的例子:
:%s/old/new/g Substitutes old with new throughout the file
:.,$s/old/new/g Substitutes old with new from the current cursor position to the end of the file
上面的示例按我的预期工作,但以下包含插入符号 ( ^
) 的示例不起作用:
:^,.s/old/new/g Substitutes old with new from the beginning of the file to the current cursor position
我尝试了,但它不起作用,那么插入符号不起作用还是我输入的命令不正确?
答案1
在vi
编辑器以及ex
and中ed
(如 BSD 系统上所示),^
地址为前一行。这意味着该命令^d
将删除上一行,^m.
将此行与上一行交换,并且将替换上一行和此行上与^,.s/old/new/g
匹配的所有字符串。old
new
编辑器是原始编辑器vim
的扩展重新实现,通常以名称、、 和安装在 Linux 系统上,没有这种寻址前一行的方式,并且将响应“vi
ex
vim
vi
ex
E492:不是编辑命令" 如果您尝试使用它。您可以使用-
或-1
代替:
-,.s/old/new/g
使用-
或-1
代替^
也适用于ed
、ex
和vi
非 GNU 系统。
POSIX 标准说以下关于这一点与ed
编辑的关系:
从历史上看,
ed
接受^
字符作为地址,在这种情况下它与<hyphen-minus>
字符相同。 POSIX.1-2017 不要求或禁止这种行为。
有一个类似的措辞对于vi
和ex
编辑器(ex
是vi
“行编辑器模式”):
从历史上看,
ex
并vi
接受该^
字符作为地址和命令的标志偏移量。在这两种情况下,它都与-
角色相同。 POSIX.1-2017 不要求或禁止这种行为。
请注意,您似乎引用的文本表示^,.
地址从文件顶部到当前行的所有行。这是不正确的。它仅处理前一行和当前行,并且仅在vi
(andex
和 ed
) 的“历史准确”实现中这样做。要寻址从编辑缓冲区开头到当前行的所有行,请使用1,.
。
^
-instead-of-拼写错误1
可能来自于这样的想法:“since$
是正则表达式中的行尾锚点,也是编辑缓冲区中最后一行的地址,^
是正则表达式,因此必须(通过对称性)是第一的编辑缓冲区的行”。
只是提供另一件琐事:该^
地址也不能在编辑器的 GNU 实现中使用ed
。与 的任何其他实现一样ed
,-
或-1
仍可用作替代方案。
答案2
您发现此命令的站点vi
是错误的。
有可能那个 1996 年的网站或其他许多未经仔细检查就复制/粘贴这些行的人之一。
Using vi, the Unix Visual Editor
…
:.,$s/old/new/g Substitutes old with new from the current
cursor position to the end of the file
:^,.s/old/new/g Substitutes old with new from the beginning
of the file to the current cursor position
© Copyright 1996 University of Washington Computing & Communications.
应该写的是:
:1,.s/old/new/g
插入符号在 下有多种用法vi
。其中之一是告诉模式区域中的行的开头,所以/^old/
当开始行时意味着“旧”,就像$
意味着行结束一样,/old$/
当结束行时意味着“旧”。
我确信这种混乱是由于这种对称性造成的。作者(Rick Ells)认为插入符号^
意味着文件的开头或行的开头,就像$
意味着文件的结尾或行的结尾一样,但事实并非如此。
碰巧插入符号在用作像 Kusalananda 指出的地址时也有特定且不同的含义,但恕我直言,这是轶事,因为我从未见过任何人使用此快捷方式,-1
更加直观。