打印两个模式之间的所有行,仅排他,仅第一实例(在sed,AWK或Perl中) [英] Print all lines between two patterns, exclusive, first instance only (in sed, AWK or Perl)
问题描述
使用sed,AWK(或Perl),如何打印两个模式(第一个实例)之间的所有行(不包括模式)? 1
Using sed, AWK (or Perl), how do you print all lines between (the first instance of) two patterns, exclusive of the patterns?1
也就是说,作为输入给出:
That is, given as input:
aaa
PATTERN1
bbb
ccc
ddd
PATTERN2
eee
甚至可能:
aaa
PATTERN1
bbb
ccc
ddd
PATTERN2
eee
fff
PATTERN1
ggg
hhh
iii
PATTERN2
jjj
在两种情况下,我都会期望:
I would expect, in both cases:
bbb
ccc
ddd
1 许多用户投票结束了该问题,并重复了要点,以证明它们是不同的.这个问题从表面上也类似于 a
1 A number of users voted to close this question as a duplicate of this one. In the end, I provided a gist that proves they are different. The question is also superficially similar to a number of others, but there is no exact match, and none of them are of high quality, and, as I believe that this specific problem is the one most commonly faced, it deserves a clear formulation, and a set of correct, clear answers.
推荐答案
使用 awk
(假设 PATTERN1
和 PATTERN2
始终存在配对,而它们中的任何一个都不会出现在配对中)
With awk
(assumes that PATTERN1
and PATTERN2
are always present in pairs and either of them do not occur inside a pair)
$ cat ip.txt
aaa
PATTERN1
bbb
ccc
ddd
PATTERN2
eee
fff
PATTERN1
ggg
hhh
iii
PATTERN2
jjj
$ awk '/PATTERN2/{exit} f; /PATTERN1/{f=1}' ip.txt
bbb
ccc
ddd
- 如果
-
/PATTERN1/{f = 1}
设置标志 如果 -
/PATTERN2/{exit}
退出 -
f;
如果设置了标志,则打印输入行 /PATTERN1/{f=1}
set flag if/PATTERN1/
is matched/PATTERN2/{exit}
exit if/PATTERN2/
is matchedf;
print input line if flag is set
/PATTERN1/
与之匹配,则/PATTERN2/
匹配,则
通用解决方案,可以在其中指定所需的块
Generic solution, where the block required can be specified
$ awk -v b=1 '/PATTERN2/ && c==b{exit} c==b; /PATTERN1/{c++}' ip.txt
bbb
ccc
ddd
$ awk -v b=2 '/PATTERN2/ && c==b{exit} c==b; /PATTERN1/{c++}' ip.txt
2
46
这篇关于打印两个模式之间的所有行,仅排他,仅第一实例(在sed,AWK或Perl中)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!