我一直在看这个问题,然后想知道如何使用纯
POSIX
实现我的答案
sed
。ex
诀窍是,虽然sed
我可以比较保持空间和模式空间以查看它们是否完全相等(用
G;/^\(.*\)\n\1$/{do something}
),但是我不知道在中进行这种测试的方法ex
。
我知道在Vim中,我可以Y
使第一行变短,然后键入
:2,$g/<C-r>0/d
以几乎执行我指定的操作-但是如果第一行包含除非常简单的字母数字文本之外的任何内容,这的确会带来麻烦,因为该行已作为正则表达式转储了进来。
,而不仅仅是用于比较的字符串。(如果第一行包含正斜杠,则该行的其余部分将被解释为命令!)
因此,如果我想删除myfile
与第一行相同的所有行,但又不想删除第一行,该如何使用ex
?为此,我该如何使用vi
?
如果某行与另一行完全匹配,是否有POSIX方法删除该行?
可能是这样的虚构语法:
:2,$g/**lines equal to "0**/d
<C-r>0
很好。我不确定仅使用Ex命令会更好,因为您必须保护特殊字符。如果没有POSIX兼容约束,我想您将使用非常不可思议的开关\V
,然后使用第二个参数是一个包含您要转义/保护的所有字符的字符串\V
的escape()
函数来保护反斜杠(因为即使使用,它也会保留其特殊含义)。。
:execute '2,$g/\V' . escape(getline(1), '\/') . '/d'
或者您可以将另一个字符用作分号,例如分号。在这种情况下,您无需在模式中保护正斜杠。它会给出以下内容::execute '2,$g;\V' . escape(getline(1), '\') . ';d'
sed
也很好。使用Vim,您经常将某些特殊任务委托给其他程序,sed
这可能是一个很好的例子。顺便说一下,您不必sed
在整个缓冲区上运行。如果只想在缓冲区的一部分上运行它,则可以指定一个范围。例如,如果您只想过滤50到100之间的行,则可以输入::50,100!<your sed command>
。
:execute '2,$g/\V' . escape(getline(1), '\') . '/d'