删除符合某个模式的 n 行(以及与该模式匹配的行)

删除符合某个模式的 n 行(以及与该模式匹配的行)

如何使用支持正则表达式的工具删除包含匹配模式的行及其后的 n 行?

换句话说,我怎样才能编写一个正则表达式来匹配包含匹配模式的行接下来的 n 行,以便我可以用什么都不替换它们?

例如,如果我有一个匹配的模式bbbb,并且还想删除输入文件中其后面的 5 行:

aldjflajdkl
aaaabbbbaaaa
1l;adfjl
2aldfjl
3adlflkdas
4aldfjd
5aldfkld
6dlafjlkdas

输出结果为:

aldjflajdkl
6dlafjlkdas

这可能简化了事情,在我的特定情况下,匹配模式()不可能bbbb包含在下面 5 行中。

sed 的解决方案已经存在,但它仅部分依赖于正则表达式,并且使用不可移植的自定义替换命令。

答案1

一个可能的解决方案是:

.*<matching pattern>(.*\r?\n){<N+1>}

其中N,我想要删除包含模式的行后的行数是多少。

对于给出的例子,这意味着:

.*bbbb(.*\r?\n){6}

这就是它在 grepWin 中的样子: grepWin 屏幕截图
附注:

  • 在“正则表达式搜索字符串匹配”选项卡中,该5aldfkld行也被标记为匹配,实际上在右侧可以看到一个滚动条
  • (grepWin 特有)由于一个小错误,当在文件上应用此搜索时,您会看到匹配数每匹配一次就会增加 7!这可能是因为匹配计数器计算匹配的行数,在这种情况下,模式涵盖 7 行:匹配的行、接下来的 5 行以及最后一个换行符到达的行
  • (sed 专用)此正则表达式不适用于sed,它不完全支持正则表达式,并且具有没有简单的方法来匹配或替换新线路

下面解释了我如何找到解决方案。

我从以下开始:

.*bbbb.*\n.*\n.*\n.*\n.*\n.*\n

这在我的系统中不起作用。但下面的方法可以工作:

.*bbbb.*\r\n.*\r\n.*\r\n.*\r\n.*\r\n.*\r\n

因此,我正在使用 CRLF 系统。然而,这看起来不太美观,也不便于携带。

我可以让它更便携一些(也更丑陋:-)),方法是:

.*bbbb.*\r?\n.*\r?\n.*\r?\n.*\r?\n.*\r?\n.*\r?\n

(回车符变为可选的)。它仍然看起来很丑,但我可以收集重复的术语:

.*bbbb(.*\r?\n){6}

本指南非常方便。

答案2

解决方案awk

awk '/bbbb/ {i=5; next} {if (i>0) i--; else print}'

当它检测到您要查找的模式时,它会将i(倒数计数器)设置为 5,并跳过其余处理(即跳到下一行输入)。特别是,它不会打印该行。(/bbbb/ {i=5+1}第一部分的说法是等效的;根据您的风格偏好选择一个。)然后,如果计数器为正数,则将其递减(减 1)以计算要删除(跳过)的行数,并且不打印;否则,打印该行。

相关内容