如何删除包含特定语法的行但我想避免包含另一个单词的行

CLE*_*420 4 linux gvim

如何删除包含特定单词的行但请记住:如果找到另一个单词,则不要删除该行。例如,我正在删除带有supgnd带有:%s/.*sup.*//g或的行:%s/.*gnd.*//g,但它也删除了一些破坏循环行的行。

我不想删除modulegnd或位于同一行的行sup。知道如何征服这条线吗?

Sté*_*las 5

你可以使用:

:v/module/s/\v.*(sup|gnd).*//
Run Code Online (Sandbox Code Playgroud)
  • :v/pattern/cmdcmd在与模式匹配的行上运行
  • \v打开非常神奇的功能,以便所有(,|字符都被视为正则表达式运算符,而无需为它们添加前缀\.

请注意,它会清空,但不会删除包含sup或的行gnd。要删除它们,因为您不能嵌套g/v命令,您可以vim在一个g命令中使用's negative look forward regexp 运算符:

:g/\v^(.*module)@!.*(sup|gnd)/d
Run Code Online (Sandbox Code Playgroud)
  • :g/pattern/cmd运行cmd在该行匹配的模式
  • (pattern)@!(使用very-magic)如果模式在该位置不匹配,则匹配零宽度,因此^(.*module)@!匹配不包含module.

还有管道到sedor的选项awk

:%!sed -e /module/b -e /sup/d -e /gnd/d
Run Code Online (Sandbox Code Playgroud)
  • /module/b对于包含module.
  • 对于不包含的行,我们继续执行接下来的两个命令,分别删除包含sup或的行gnd

或者:

:%!awk '/sup|gnd/ && ! /module/'
Run Code Online (Sandbox Code Playgroud)

如果您想找到那些需要删除这些行的文件并删除它们,您可能希望跳过vim并使用文本处理实用程序完成整个操作。在 GNU 系统上:

find . ! -name '*.back' -type f -size +3c -exec gawk '
  /sup|gnd/ && ! /module/ {printf "%s\0", FILENAME; nextfile}' '{}' + |
  xargs -r0 sed -i.back -e /module/b -e /sup/d -e /gnd/d
Run Code Online (Sandbox Code Playgroud)

(此处将原始文件的备份另存为the-file.back,如果不需要备份,请更改-i.back-i)。

  • find查找名称不以 in 结尾.back且大小至少为 4 个字节的常规文件(较小的文件不可能包含包含supgnd(和行分隔符)的行),并gawk以相应文件的路径作为参数运行.
  • gawk在任何匹配的文件中找到一行时,它会打印FILENAME以 NUL 字符(for xargs -0)分隔的文件(特殊变量)的路径并跳到下一个文件。
  • xargs -r0gawk输出以sed这些文件路径作为参数运行的进程。
  • sed 就地编辑文件。