sed or awk: delete n lines following a pattern
我如何在sed(或任何类似的工具 - 例如awk)中混合模式和数值范围? 我想要做的是匹配文件中的某些行,并在继续之前删除接下来的n行,我想将其作为管道的一部分。
我会去看看。
要在模式后删除5行(包括带有模式的行):
1 | sed -e '/pattern/,+5d' file.txt |
要在图案后删除5行(不包括带图案的行):
1 | sed -e '/pattern/{n;N;N;N;N;d}' file.txt |
简单的
假设用于查找匹配行的正则表达式存储在shell变量
如果还应跳过匹配行(跳过
1 2 | ... | awk -v regex="$regex" -v count="$count" \ '$0 ~ regex { skip=count; next } --skip >= 0 { next } 1' |
如果不应跳过匹配的行(跳过匹配后的
1 2 | ... | awk -v regex="$regex" -v count="$count" \ '$0 ~ regex { skip=count; print; next } --skip >= 0 { next } 1' |
说明:
-
-v regex="$regex" -v count="$count" 基于同名的shell变量定义awk 变量。 -
$0 ~ regex 与感兴趣的线匹配-
{ skip=count; next } 初始化跳过计数并前进到下一行,有效地跳过匹配行;在第二个解决方案中,next 之前的print 确保不会跳过它。 -
--skip >= 0 减少跳过计数并在(仍然)> = 0时采取措施,这意味着应该跳过手头的行。 -
{ next } 进入下一行,有效地跳过当前行
-
-
1 是{ print } 的常用简写;也就是说,简单地打印当前行- 只有非匹配和非跳过的行才能到达此命令。
-
1 等同于{ print } 的原因是1 被解释为布尔模式,根据定义,它总是求值为true,这意味着它的关联动作(块)是无条件执行的。由于在这种情况下没有关联的操作,awk 默认为打印该行。
没有GNU扩展(例如在macOS上):
在图案后删除5行(包括带图案的行)
1 | sed -e '/pattern/{N;N;N;N;d;}' |
添加
使用Perl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | $ cat delete_5lines.txt 1 2 3 4 5 hello 6 7 8 9 10 11 hai $ perl -ne ' BEGIN{$y=1} $y=$. if /hello/ ; print if $y==1 or $.-$y > 5 ' delete_5lines.txt 1 2 3 4 11 hai $ |
这可能对你有用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | cat <<! >pattern_number.txt > 5 3 > 10 1 > 15 5 > ! sed 's|\(\S*\) \(\S*\)|/\1/,+\2{//!d}|' pattern_number.txt | sed -f - <(seq 21) 1 2 3 4 5 9 10 12 13 14 15 21 |
此解决方案允许您传递"n"作为参数,它将从文件中读取您的模式:
1 2 3 4 5 6 7 8 9 10 11 12 13 | awk -v n=5 ' NR == FNR {pattern[$0]; next} { for (patt in pattern) { if ($0 ~ patt) { print # remove if you want to exclude a matched line for (i=0; i<n; i++) getline next } } } ' file.with.patterns - |
名为" -"的文件表示awk的stdin,因此这适用于您的管道