我如何在sed中混合模式和数值范围(或任何类似的工具 - 例如awk)?我想要做的是匹配文件中的某些行,并在继续之前删除接下来的n行,我想将其作为管道的一部分。
答案 0 :(得分:152)
我会去看看。
删除模式后的5行(包括带模式的行):
sed -e '/pattern/,+5d' file.txt
要在图案后删除5行(不包括带图案的行):
sed -e '/pattern/{n;N;N;N;N;d}' file.txt
答案 1 :(得分:5)
简单awk
解决方案:
假设用于查找匹配行的正则表达式存储在shell变量$regex
中,以及要在$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'
根据同名的 shell 变量定义-v regex="$regex" -v count="$count"
个变量。awk
匹配感兴趣的线条
$0 ~ regex
初始化跳过计数并继续到下一行,有效地跳过匹配行;在第二个解决方案中,{ skip=count; next }
之前的print
确保不跳过。next
减少跳过次数,如果(仍然)> = 0则采取措施,这意味着应该跳过手边的行。--skip >= 0
进入下一行,有效地跳过当前行{ next }
是1
的常用简写;也就是说,简单地打印当前行
{ print }
等同于1
的原因是{ print }
被解释为布尔模式,根据定义,它总是计算为true,这意味着它的相关操作( block)无条件执行。由于在这种情况下存在否关联操作,1
默认为打印该行。 答案 2 :(得分:2)
此解决方案允许您传递“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的stdin,因此这适用于您的管道
答案 3 :(得分:2)
这可能对您有用:
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
答案 4 :(得分:2)
使用Perl
$ 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
$
答案 5 :(得分:1)
没有GNU扩展名(例如在macOS上):
要删除图案后的5行(包括带有图案的行)
sed -e '/pattern/{N;N;N;N;d;}'
添加-i ''
进行就地编辑。