如何使用支持正则表达式的工具删除包含匹配模式的行及其后的 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 中的样子:
附注:
- 在“正则表达式搜索字符串匹配”选项卡中,该
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)以计算要删除(跳过)的行数,并且不打印;否则,打印该行。