这个问题的答案:
不关心匹配模式之间的多个行序列。因此,例如,sed -n '/startpattern_here/,/endpattern_here/p'
将打印位于这些图案出现之间的几个行序列。
但是,假设我只想打印最后的文件中的此类序列。我可以用 sed 做到这一点吗?如果没有,我想可能是 awk?还有别的事吗?
笔记:
- 您可以假设这些序列不重叠。
- 起始和结束图案线应该包含在输出中。
- 假设较低复杂性模式的答案也是有效的(尽管不是最佳的)。
答案1
假设您想要完整的正则表达式测试,这可能会起作用:
awk '/startpattern_here/ {buf="";f=1}
f{buf=buf $0 "\n"}
/endpattern_here/ {f=0; lastcomplete=buf}
END{printf("%s",lastcomplete)}' file.txt
这将确保只打印完整的开始-停止模式。
测试用例:
irrelevant
irrelevant
irrelevant
startpattern_here
relevant_but_dont_show_1
relevant_but_dont_show_1
relevant_but_dont_show_1
endpattern_here
irrelevant
irrelevant
startpattern_here
relevant_but_dont_show_2
relevant_but_dont_show_2
relevant_but_dont_show_2
endpattern_here
irrelevant
irrelevant
startpattern_here
relevant_and_show
relevant_and_show
relevant_and_show
endpattern_here
irrelevant
startpattern_here
incomplete_dont_show
结果:
startpattern_here
relevant_and_show
relevant_and_show
relevant_and_show
endpattern_here
笔记如果要抑制开始模式和结束模式的输出,只需交换规则/startpattern_here/ { ... }
和/endpattern_here/ { ... }
,即先放置“结束模式”规则,然后将“开始模式”规则放在该END
规则之前。
答案2
tac 和 awk 的组合
tac file \
| awk '
!p && /endpattern_here/ {p = 1}
p {print}
p && /startpattern_here/ {exit}
' \
| tac
答案3
和前任(POSIX 编辑器)非常简单:
printf '%s\n' 1 '?END?' '?START?,.p' | ex -s file
1
转到文件的第一行。如果END
是文件的最后一行,这是必要的。?END?
向后查找(环绕文件末尾)END
,从而找到它在文件中的最后一次出现。?START?,.p
打印从START
上一个地址到当前地址的所有内容。
下面是一个使用here-docs 而不是 的示例printf
,只是为了多样性。
$ cat file
zdk
START
b12
END
kdn
START
000
111
END
START
ddd
$ ex -s file <<EOF
> 1
> ?END?
> ?START?,.p
> EOF
START
000
111
END
答案4
一种方法是简单地存储每组,用下一组覆盖它,并在到达最后时打印您保留的组:
awk '{
if(/startpattern_here/){
a=1;
lines=$0;
next
}
if(a){
lines=lines"\n"$0
}
if(/end_pattern/){
a=0
}
}
END{
print lines
}' file
例如,使用此测试文件:
startpattern_here
line 1
line 2
line 3
end_pattern
startpattern_here
line 1b
line 2b
line 3b
end_pattern
startpattern_here
line 1c
line 2c
line 3c
end_pattern
我得到:
$ awk '{ if(/startpattern_here/){a=1; lines=$0; next} if(a){lines=lines"\n"$0} if(/end_pattern/){a=0}} END{print lines}' file
startpattern_here
line 1c
line 2c
line 3c
end_pattern