Answers:
我会去解决的。
要删除模式后的5行(包括带有模式的行):
sed -e '/pattern/,+5d' file.txt
要删除模式后的5行(不包括带有模式的行):
sed -e '/pattern/{n;N;N;N;N;d}' file.txt
/pattern/,+5
定义一个范围,该范围以包含“ pattern”的行开始(/pattern/
),然后以5行结束+5
。最后一个字符d
是在该范围内的每一行上运行的命令,即“删除”。在第二个配方中,它不匹配范围,而是仅匹配包含模式(/pattern/
)的行,然后运行一系列命令:{n;N;N;N;N;d}
,该命令基本上会打印下一行(n
),然后读取并最终丢弃接下来的4行(N;N;N;N;d
)。
sed -e '/pattern/{n;N;N;N;N;d;}' file.txt
something
操作:sed -E '/^something$/,$d'
,其中-E
POSIX可移植性扩展正则表达式是。
简单的awk
解决方案:
假定用于查找匹配行的正则表达式存储在shell变量中$regex
,而要跳过的行数也存储在shell变量中$count
。
如果还应跳过匹配的行(也跳过$count + 1
行):
... | awk -v regex="$regex" -v count="$count" \
'$0 ~ regex { skip=count; next } --skip >= 0 { next } 1'
如果不应该跳过匹配的行(跳过匹配之后的$count
行):
... | awk -v regex="$regex" -v count="$count" \
'$0 ~ regex { skip=count; print; next } --skip >= 0 { next } 1'
说明:
-v regex="$regex" -v count="$count"
awk
基于同名的shell变量定义变量。$0 ~ regex
符合兴趣线
{ skip=count; next }
初始化跳过计数并前进到下一行,有效地跳过匹配的行;在第二个解决方案中,print
before next
确保不会跳过它。--skip >= 0
减少跳过计数并在(仍然)> = 0时采取措施,这意味着应跳过当前行。{ next }
前进到下一行,有效跳过当前行1
是常用的简写{ print }
; 也就是说,仅打印当前行
1
是相当于{ print }
是1
被解释为布尔图案,根据定义总是评估为真,这意味着被无条件地执行其相关联的动作(块)。由于在这种情况下没有关联的操作,因此awk
默认情况下将打印该行。这可能对您有用:
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
pattern_number.txt
是一个2列文件,在第1列中包含要匹配的模式,在第2列中包含要跳过的行数。第一个sed
命令将文件转换为sed
执行相应匹配和跳过操作的脚本;该脚本是通过-f
和stdin(-
)提供给第二个sed
命令的。第二个sed
命令对示例临时输入文件进行操作,该示例输入文件由的输出组成,seq 21
以证明其有效。
此解决方案允许您传递“ n”作为参数,它将从文件读取模式:
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
}
}
print
}
' file.with.patterns -
名为“-”的文件表示awk的标准输入,因此适合您的管道
+N
模式是GNU扩展。在第二个示例中将第n
一个更改为anN
,以使其包含带有模式的行。