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

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

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

我不想删除与ormodule位于同一行的行。知道如何征服这条线吗?gndsup

答案1

你可以使用:

:v/module/s/\v.*(sup|gnd).*//
  • :v/pattern/cmd运行cmd在执行的线路上不是匹配模式
  • \v打开非常神奇这样所有的(,|字符都被视为正则表达式运算符,而不需要在它们前面加上前缀\.

请注意,它空了但除此之外不会消除sup包含或的行gnd。要删除它们,由于您无法嵌套g/v命令,您可以vim在一个命令中使用 's 负向前看正则表达式运算符g

:g/\v^(.*module)@!.*(sup|gnd)/d
  • :g/pattern/cmd运行cmd在线路上匹配模式
  • (pattern)@!(和非常神奇) 与零宽度匹配,如果图案在该位置不匹配,因此^(.*module)@!在不包含 的行的开头匹配module

还可以选择通过管道连接到sedor awk

:%!sed -e /module/b -e /sup/d -e /gnd/d
  • /module/b对于包含 . 的行进行分支(并打印该行)module
  • 对于不包含的行,我们继续执行接下来的两个命令,分别删除包含sup或的行gnd

或者:

:%!awk '/sup|gnd/ && ! /module/'

如果你想寻找那些需要删除这些行并删除它们的文件,您可能想跳过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

(这里将原文件的备份保存为the-file.back,如果不需要备份则改为 )-i.back-i

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

答案2

发现它为:v/(模块\|输入\|输出)/s/\v。/

相关内容