How to print lines between pattern1 and 2nd match of pattern2?
Clash Royale CLAN TAG#URR8PPP
Test file is given below:
PATTERN1
a
b
c
PATTERN2
d
e
f
PATTERN2
g
h
I want to print line between PATTERN1
and 2nd match of PATTERN2
:
PATTERN1
a
b
c
PATTERN2
d
e
f
PATTERN2
text-processing awk sed
add a comment |
Test file is given below:
PATTERN1
a
b
c
PATTERN2
d
e
f
PATTERN2
g
h
I want to print line between PATTERN1
and 2nd match of PATTERN2
:
PATTERN1
a
b
c
PATTERN2
d
e
f
PATTERN2
text-processing awk sed
add a comment |
Test file is given below:
PATTERN1
a
b
c
PATTERN2
d
e
f
PATTERN2
g
h
I want to print line between PATTERN1
and 2nd match of PATTERN2
:
PATTERN1
a
b
c
PATTERN2
d
e
f
PATTERN2
text-processing awk sed
Test file is given below:
PATTERN1
a
b
c
PATTERN2
d
e
f
PATTERN2
g
h
I want to print line between PATTERN1
and 2nd match of PATTERN2
:
PATTERN1
a
b
c
PATTERN2
d
e
f
PATTERN2
text-processing awk sed
text-processing awk sed
edited Jun 28 '16 at 11:50
jimmij
32.3k875109
32.3k875109
asked Jun 28 '16 at 11:04
sachinsachin
686
686
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
Here's one way to do it with sed
:
sed '/PATTERN1/,$!d;/PATTERN2/x;//x;q;;g;' infile
This just deletes all lines (if any) up to the first occurrence of PATTERN1
and then, on each line that matches PATTERN2
it ex
changes buffers. If the new pattern space also matches, it means it's the 2nd occurrence so it ex
changes back and q
uits (after auto-printing). If it doesn't match it means it's the 1st occurrence so it copies the hold space content over the pattern space via g
(so now there's a line matching PATTERN2
in the hold buffer) and goes on...
and another way with awk
:
awk '/PATTERN1/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile
It starts printing and counting lines matching PATTERN2
only when encountering a line matching PATTERN1
and exits when c
ounter reaches 2
.
in my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the awk command is not working with it. can you help me. i tried awk '/$xx/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile but it is not working.
– sachin
Jun 29 '16 at 3:52
@sachin -awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile
– don_crissti
Jun 29 '16 at 8:58
in another case, it should print data only if the PATTERN1 start the line. any solution ?
– sachin
Jul 8 '16 at 4:06
please provide solution to find the pattern at the start of line in the given command. awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile . because in my case the pattern 1 is a variable and coming in the start of line.
– sachin
Jul 8 '16 at 11:37
thanks for the reply, its working. can you please explain the whole command ?
– sachin
Jul 8 '16 at 11:48
|
show 3 more comments
The right tool for this job is pcregrep
:
pcregrep -M 'PATTERN1(.|n)*PATTERN2' file
where option -M
allows pattern to match more than one line and (.|n)*
match any character or newline zero or more times.
Notice that we took advantage of the greediness of the grep. If you would want to print form pattern1 up to the first occurrence of the pattern2, then non-greedy *?
should be used instead of *
.
As a generalization, to print up to the n
th occurrence of PATTERN2:
pcregrep -M 'PATTERN1((.|n)*?PATTERN2)n' file
Change n
to actual number you need.
As you are using multiline flag, so why not justpcregrep -M 'PATTERN1.*PATTERN2' file
?
– heemayl
Jun 29 '16 at 1:51
n my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the command provided by you , is not working with it. can you help me. i tried pcregrep -M '$xx((.|n)*?PATTERN2)2' file infile but it is not working
– sachin
Jun 29 '16 at 3:57
@heemayl Because you have to provide both:-M
andn
, otherwise it doesn't work.
– jimmij
Jun 29 '16 at 7:49
@sachin Trypcregrep -M "$xx"'((.|n)*?PATTERN2)2' file
. The variable have to be inside double quotes, otherwise it is not expanded.
– jimmij
Jun 29 '16 at 7:51
add a comment |
Just use flags:
$ awk '/PATTERN1/flag=2;next flag; /PATTERN2/flag--' file
a
b
c
PATTERN2
d
e
f
PATTERN2
That is: when you find PATTERN1
set the flag to a positive value; in particular, 2. Then, when you find PATTERN2
, decrease that flag in one. This way, it will exhaust after the second match. In between, use flag
as a value that triggers the print $0
when it has a true value (2 or 1).
This will fail in any of the following circumstances: 1) if there's at least one line matchingPATTERN2
before the line matchingPATTERN1
(but not immediately before it) 2) if there are more than two lines matchingPATTERN2
after the line matchingPATTERN1
and the third line matchingPATTERN2
isn't the last line in the file or 3) if there's a second line matchingPATTERN1
in between the first two (of several) lines matchingPATTERN2
that follow the first line matchingPATTERN1
– don_crissti
Jun 28 '16 at 20:29
Would it be possible to not print the last PATTERN2?
– Markus Lindberg
Jun 18 '18 at 15:14
@MarkusLindberg you should either create some kind of buffering (otherwise, how do you know if it is the last PATTERN2?) or read the file backwards
– fedorqui
Jul 4 '18 at 6:39
add a comment |
If we told regarding sed
is to much easy to collect nesessary lines then print
sed -n '
/PATTERN1/
:1
$!N
/(PATTERN2).*1/!b1
p
' file
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f292573%2fhow-to-print-lines-between-pattern1-and-2nd-match-of-pattern2%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
Here's one way to do it with sed
:
sed '/PATTERN1/,$!d;/PATTERN2/x;//x;q;;g;' infile
This just deletes all lines (if any) up to the first occurrence of PATTERN1
and then, on each line that matches PATTERN2
it ex
changes buffers. If the new pattern space also matches, it means it's the 2nd occurrence so it ex
changes back and q
uits (after auto-printing). If it doesn't match it means it's the 1st occurrence so it copies the hold space content over the pattern space via g
(so now there's a line matching PATTERN2
in the hold buffer) and goes on...
and another way with awk
:
awk '/PATTERN1/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile
It starts printing and counting lines matching PATTERN2
only when encountering a line matching PATTERN1
and exits when c
ounter reaches 2
.
in my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the awk command is not working with it. can you help me. i tried awk '/$xx/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile but it is not working.
– sachin
Jun 29 '16 at 3:52
@sachin -awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile
– don_crissti
Jun 29 '16 at 8:58
in another case, it should print data only if the PATTERN1 start the line. any solution ?
– sachin
Jul 8 '16 at 4:06
please provide solution to find the pattern at the start of line in the given command. awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile . because in my case the pattern 1 is a variable and coming in the start of line.
– sachin
Jul 8 '16 at 11:37
thanks for the reply, its working. can you please explain the whole command ?
– sachin
Jul 8 '16 at 11:48
|
show 3 more comments
Here's one way to do it with sed
:
sed '/PATTERN1/,$!d;/PATTERN2/x;//x;q;;g;' infile
This just deletes all lines (if any) up to the first occurrence of PATTERN1
and then, on each line that matches PATTERN2
it ex
changes buffers. If the new pattern space also matches, it means it's the 2nd occurrence so it ex
changes back and q
uits (after auto-printing). If it doesn't match it means it's the 1st occurrence so it copies the hold space content over the pattern space via g
(so now there's a line matching PATTERN2
in the hold buffer) and goes on...
and another way with awk
:
awk '/PATTERN1/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile
It starts printing and counting lines matching PATTERN2
only when encountering a line matching PATTERN1
and exits when c
ounter reaches 2
.
in my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the awk command is not working with it. can you help me. i tried awk '/$xx/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile but it is not working.
– sachin
Jun 29 '16 at 3:52
@sachin -awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile
– don_crissti
Jun 29 '16 at 8:58
in another case, it should print data only if the PATTERN1 start the line. any solution ?
– sachin
Jul 8 '16 at 4:06
please provide solution to find the pattern at the start of line in the given command. awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile . because in my case the pattern 1 is a variable and coming in the start of line.
– sachin
Jul 8 '16 at 11:37
thanks for the reply, its working. can you please explain the whole command ?
– sachin
Jul 8 '16 at 11:48
|
show 3 more comments
Here's one way to do it with sed
:
sed '/PATTERN1/,$!d;/PATTERN2/x;//x;q;;g;' infile
This just deletes all lines (if any) up to the first occurrence of PATTERN1
and then, on each line that matches PATTERN2
it ex
changes buffers. If the new pattern space also matches, it means it's the 2nd occurrence so it ex
changes back and q
uits (after auto-printing). If it doesn't match it means it's the 1st occurrence so it copies the hold space content over the pattern space via g
(so now there's a line matching PATTERN2
in the hold buffer) and goes on...
and another way with awk
:
awk '/PATTERN1/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile
It starts printing and counting lines matching PATTERN2
only when encountering a line matching PATTERN1
and exits when c
ounter reaches 2
.
Here's one way to do it with sed
:
sed '/PATTERN1/,$!d;/PATTERN2/x;//x;q;;g;' infile
This just deletes all lines (if any) up to the first occurrence of PATTERN1
and then, on each line that matches PATTERN2
it ex
changes buffers. If the new pattern space also matches, it means it's the 2nd occurrence so it ex
changes back and q
uits (after auto-printing). If it doesn't match it means it's the 1st occurrence so it copies the hold space content over the pattern space via g
(so now there's a line matching PATTERN2
in the hold buffer) and goes on...
and another way with awk
:
awk '/PATTERN1/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile
It starts printing and counting lines matching PATTERN2
only when encountering a line matching PATTERN1
and exits when c
ounter reaches 2
.
edited Jun 28 '16 at 12:22
answered Jun 28 '16 at 11:30
don_crisstidon_crissti
51.6k15141168
51.6k15141168
in my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the awk command is not working with it. can you help me. i tried awk '/$xx/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile but it is not working.
– sachin
Jun 29 '16 at 3:52
@sachin -awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile
– don_crissti
Jun 29 '16 at 8:58
in another case, it should print data only if the PATTERN1 start the line. any solution ?
– sachin
Jul 8 '16 at 4:06
please provide solution to find the pattern at the start of line in the given command. awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile . because in my case the pattern 1 is a variable and coming in the start of line.
– sachin
Jul 8 '16 at 11:37
thanks for the reply, its working. can you please explain the whole command ?
– sachin
Jul 8 '16 at 11:48
|
show 3 more comments
in my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the awk command is not working with it. can you help me. i tried awk '/$xx/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile but it is not working.
– sachin
Jun 29 '16 at 3:52
@sachin -awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile
– don_crissti
Jun 29 '16 at 8:58
in another case, it should print data only if the PATTERN1 start the line. any solution ?
– sachin
Jul 8 '16 at 4:06
please provide solution to find the pattern at the start of line in the given command. awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile . because in my case the pattern 1 is a variable and coming in the start of line.
– sachin
Jul 8 '16 at 11:37
thanks for the reply, its working. can you please explain the whole command ?
– sachin
Jul 8 '16 at 11:48
in my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the awk command is not working with it. can you help me. i tried awk '/$xx/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile but it is not working.
– sachin
Jun 29 '16 at 3:52
in my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the awk command is not working with it. can you help me. i tried awk '/$xx/t=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile but it is not working.
– sachin
Jun 29 '16 at 3:52
@sachin -
awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile
– don_crissti
Jun 29 '16 at 8:58
@sachin -
awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile
– don_crissti
Jun 29 '16 at 8:58
in another case, it should print data only if the PATTERN1 start the line. any solution ?
– sachin
Jul 8 '16 at 4:06
in another case, it should print data only if the PATTERN1 start the line. any solution ?
– sachin
Jul 8 '16 at 4:06
please provide solution to find the pattern at the start of line in the given command. awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile . because in my case the pattern 1 is a variable and coming in the start of line.
– sachin
Jul 8 '16 at 11:37
please provide solution to find the pattern at the start of line in the given command. awk -v m="$xx" '$0~mt=1; t==1print; if (/PATTERN2/)c++; c==2exit' infile . because in my case the pattern 1 is a variable and coming in the start of line.
– sachin
Jul 8 '16 at 11:37
thanks for the reply, its working. can you please explain the whole command ?
– sachin
Jul 8 '16 at 11:48
thanks for the reply, its working. can you please explain the whole command ?
– sachin
Jul 8 '16 at 11:48
|
show 3 more comments
The right tool for this job is pcregrep
:
pcregrep -M 'PATTERN1(.|n)*PATTERN2' file
where option -M
allows pattern to match more than one line and (.|n)*
match any character or newline zero or more times.
Notice that we took advantage of the greediness of the grep. If you would want to print form pattern1 up to the first occurrence of the pattern2, then non-greedy *?
should be used instead of *
.
As a generalization, to print up to the n
th occurrence of PATTERN2:
pcregrep -M 'PATTERN1((.|n)*?PATTERN2)n' file
Change n
to actual number you need.
As you are using multiline flag, so why not justpcregrep -M 'PATTERN1.*PATTERN2' file
?
– heemayl
Jun 29 '16 at 1:51
n my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the command provided by you , is not working with it. can you help me. i tried pcregrep -M '$xx((.|n)*?PATTERN2)2' file infile but it is not working
– sachin
Jun 29 '16 at 3:57
@heemayl Because you have to provide both:-M
andn
, otherwise it doesn't work.
– jimmij
Jun 29 '16 at 7:49
@sachin Trypcregrep -M "$xx"'((.|n)*?PATTERN2)2' file
. The variable have to be inside double quotes, otherwise it is not expanded.
– jimmij
Jun 29 '16 at 7:51
add a comment |
The right tool for this job is pcregrep
:
pcregrep -M 'PATTERN1(.|n)*PATTERN2' file
where option -M
allows pattern to match more than one line and (.|n)*
match any character or newline zero or more times.
Notice that we took advantage of the greediness of the grep. If you would want to print form pattern1 up to the first occurrence of the pattern2, then non-greedy *?
should be used instead of *
.
As a generalization, to print up to the n
th occurrence of PATTERN2:
pcregrep -M 'PATTERN1((.|n)*?PATTERN2)n' file
Change n
to actual number you need.
As you are using multiline flag, so why not justpcregrep -M 'PATTERN1.*PATTERN2' file
?
– heemayl
Jun 29 '16 at 1:51
n my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the command provided by you , is not working with it. can you help me. i tried pcregrep -M '$xx((.|n)*?PATTERN2)2' file infile but it is not working
– sachin
Jun 29 '16 at 3:57
@heemayl Because you have to provide both:-M
andn
, otherwise it doesn't work.
– jimmij
Jun 29 '16 at 7:49
@sachin Trypcregrep -M "$xx"'((.|n)*?PATTERN2)2' file
. The variable have to be inside double quotes, otherwise it is not expanded.
– jimmij
Jun 29 '16 at 7:51
add a comment |
The right tool for this job is pcregrep
:
pcregrep -M 'PATTERN1(.|n)*PATTERN2' file
where option -M
allows pattern to match more than one line and (.|n)*
match any character or newline zero or more times.
Notice that we took advantage of the greediness of the grep. If you would want to print form pattern1 up to the first occurrence of the pattern2, then non-greedy *?
should be used instead of *
.
As a generalization, to print up to the n
th occurrence of PATTERN2:
pcregrep -M 'PATTERN1((.|n)*?PATTERN2)n' file
Change n
to actual number you need.
The right tool for this job is pcregrep
:
pcregrep -M 'PATTERN1(.|n)*PATTERN2' file
where option -M
allows pattern to match more than one line and (.|n)*
match any character or newline zero or more times.
Notice that we took advantage of the greediness of the grep. If you would want to print form pattern1 up to the first occurrence of the pattern2, then non-greedy *?
should be used instead of *
.
As a generalization, to print up to the n
th occurrence of PATTERN2:
pcregrep -M 'PATTERN1((.|n)*?PATTERN2)n' file
Change n
to actual number you need.
edited Jun 28 '16 at 11:55
answered Jun 28 '16 at 11:43
jimmijjimmij
32.3k875109
32.3k875109
As you are using multiline flag, so why not justpcregrep -M 'PATTERN1.*PATTERN2' file
?
– heemayl
Jun 29 '16 at 1:51
n my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the command provided by you , is not working with it. can you help me. i tried pcregrep -M '$xx((.|n)*?PATTERN2)2' file infile but it is not working
– sachin
Jun 29 '16 at 3:57
@heemayl Because you have to provide both:-M
andn
, otherwise it doesn't work.
– jimmij
Jun 29 '16 at 7:49
@sachin Trypcregrep -M "$xx"'((.|n)*?PATTERN2)2' file
. The variable have to be inside double quotes, otherwise it is not expanded.
– jimmij
Jun 29 '16 at 7:51
add a comment |
As you are using multiline flag, so why not justpcregrep -M 'PATTERN1.*PATTERN2' file
?
– heemayl
Jun 29 '16 at 1:51
n my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the command provided by you , is not working with it. can you help me. i tried pcregrep -M '$xx((.|n)*?PATTERN2)2' file infile but it is not working
– sachin
Jun 29 '16 at 3:57
@heemayl Because you have to provide both:-M
andn
, otherwise it doesn't work.
– jimmij
Jun 29 '16 at 7:49
@sachin Trypcregrep -M "$xx"'((.|n)*?PATTERN2)2' file
. The variable have to be inside double quotes, otherwise it is not expanded.
– jimmij
Jun 29 '16 at 7:51
As you are using multiline flag, so why not just
pcregrep -M 'PATTERN1.*PATTERN2' file
?– heemayl
Jun 29 '16 at 1:51
As you are using multiline flag, so why not just
pcregrep -M 'PATTERN1.*PATTERN2' file
?– heemayl
Jun 29 '16 at 1:51
n my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the command provided by you , is not working with it. can you help me. i tried pcregrep -M '$xx((.|n)*?PATTERN2)2' file infile but it is not working
– sachin
Jun 29 '16 at 3:57
n my case PATTERN1 is a variable. means xx=PATTERN1 so i want to use $xx instead of PATTERN1. but the command provided by you , is not working with it. can you help me. i tried pcregrep -M '$xx((.|n)*?PATTERN2)2' file infile but it is not working
– sachin
Jun 29 '16 at 3:57
@heemayl Because you have to provide both:
-M
and n
, otherwise it doesn't work.– jimmij
Jun 29 '16 at 7:49
@heemayl Because you have to provide both:
-M
and n
, otherwise it doesn't work.– jimmij
Jun 29 '16 at 7:49
@sachin Try
pcregrep -M "$xx"'((.|n)*?PATTERN2)2' file
. The variable have to be inside double quotes, otherwise it is not expanded.– jimmij
Jun 29 '16 at 7:51
@sachin Try
pcregrep -M "$xx"'((.|n)*?PATTERN2)2' file
. The variable have to be inside double quotes, otherwise it is not expanded.– jimmij
Jun 29 '16 at 7:51
add a comment |
Just use flags:
$ awk '/PATTERN1/flag=2;next flag; /PATTERN2/flag--' file
a
b
c
PATTERN2
d
e
f
PATTERN2
That is: when you find PATTERN1
set the flag to a positive value; in particular, 2. Then, when you find PATTERN2
, decrease that flag in one. This way, it will exhaust after the second match. In between, use flag
as a value that triggers the print $0
when it has a true value (2 or 1).
This will fail in any of the following circumstances: 1) if there's at least one line matchingPATTERN2
before the line matchingPATTERN1
(but not immediately before it) 2) if there are more than two lines matchingPATTERN2
after the line matchingPATTERN1
and the third line matchingPATTERN2
isn't the last line in the file or 3) if there's a second line matchingPATTERN1
in between the first two (of several) lines matchingPATTERN2
that follow the first line matchingPATTERN1
– don_crissti
Jun 28 '16 at 20:29
Would it be possible to not print the last PATTERN2?
– Markus Lindberg
Jun 18 '18 at 15:14
@MarkusLindberg you should either create some kind of buffering (otherwise, how do you know if it is the last PATTERN2?) or read the file backwards
– fedorqui
Jul 4 '18 at 6:39
add a comment |
Just use flags:
$ awk '/PATTERN1/flag=2;next flag; /PATTERN2/flag--' file
a
b
c
PATTERN2
d
e
f
PATTERN2
That is: when you find PATTERN1
set the flag to a positive value; in particular, 2. Then, when you find PATTERN2
, decrease that flag in one. This way, it will exhaust after the second match. In between, use flag
as a value that triggers the print $0
when it has a true value (2 or 1).
This will fail in any of the following circumstances: 1) if there's at least one line matchingPATTERN2
before the line matchingPATTERN1
(but not immediately before it) 2) if there are more than two lines matchingPATTERN2
after the line matchingPATTERN1
and the third line matchingPATTERN2
isn't the last line in the file or 3) if there's a second line matchingPATTERN1
in between the first two (of several) lines matchingPATTERN2
that follow the first line matchingPATTERN1
– don_crissti
Jun 28 '16 at 20:29
Would it be possible to not print the last PATTERN2?
– Markus Lindberg
Jun 18 '18 at 15:14
@MarkusLindberg you should either create some kind of buffering (otherwise, how do you know if it is the last PATTERN2?) or read the file backwards
– fedorqui
Jul 4 '18 at 6:39
add a comment |
Just use flags:
$ awk '/PATTERN1/flag=2;next flag; /PATTERN2/flag--' file
a
b
c
PATTERN2
d
e
f
PATTERN2
That is: when you find PATTERN1
set the flag to a positive value; in particular, 2. Then, when you find PATTERN2
, decrease that flag in one. This way, it will exhaust after the second match. In between, use flag
as a value that triggers the print $0
when it has a true value (2 or 1).
Just use flags:
$ awk '/PATTERN1/flag=2;next flag; /PATTERN2/flag--' file
a
b
c
PATTERN2
d
e
f
PATTERN2
That is: when you find PATTERN1
set the flag to a positive value; in particular, 2. Then, when you find PATTERN2
, decrease that flag in one. This way, it will exhaust after the second match. In between, use flag
as a value that triggers the print $0
when it has a true value (2 or 1).
answered Jun 28 '16 at 13:11
fedorquifedorqui
4,20222158
4,20222158
This will fail in any of the following circumstances: 1) if there's at least one line matchingPATTERN2
before the line matchingPATTERN1
(but not immediately before it) 2) if there are more than two lines matchingPATTERN2
after the line matchingPATTERN1
and the third line matchingPATTERN2
isn't the last line in the file or 3) if there's a second line matchingPATTERN1
in between the first two (of several) lines matchingPATTERN2
that follow the first line matchingPATTERN1
– don_crissti
Jun 28 '16 at 20:29
Would it be possible to not print the last PATTERN2?
– Markus Lindberg
Jun 18 '18 at 15:14
@MarkusLindberg you should either create some kind of buffering (otherwise, how do you know if it is the last PATTERN2?) or read the file backwards
– fedorqui
Jul 4 '18 at 6:39
add a comment |
This will fail in any of the following circumstances: 1) if there's at least one line matchingPATTERN2
before the line matchingPATTERN1
(but not immediately before it) 2) if there are more than two lines matchingPATTERN2
after the line matchingPATTERN1
and the third line matchingPATTERN2
isn't the last line in the file or 3) if there's a second line matchingPATTERN1
in between the first two (of several) lines matchingPATTERN2
that follow the first line matchingPATTERN1
– don_crissti
Jun 28 '16 at 20:29
Would it be possible to not print the last PATTERN2?
– Markus Lindberg
Jun 18 '18 at 15:14
@MarkusLindberg you should either create some kind of buffering (otherwise, how do you know if it is the last PATTERN2?) or read the file backwards
– fedorqui
Jul 4 '18 at 6:39
This will fail in any of the following circumstances: 1) if there's at least one line matching
PATTERN2
before the line matching PATTERN1
(but not immediately before it) 2) if there are more than two lines matching PATTERN2
after the line matching PATTERN1
and the third line matching PATTERN2
isn't the last line in the file or 3) if there's a second line matching PATTERN1
in between the first two (of several) lines matching PATTERN2
that follow the first line matching PATTERN1
– don_crissti
Jun 28 '16 at 20:29
This will fail in any of the following circumstances: 1) if there's at least one line matching
PATTERN2
before the line matching PATTERN1
(but not immediately before it) 2) if there are more than two lines matching PATTERN2
after the line matching PATTERN1
and the third line matching PATTERN2
isn't the last line in the file or 3) if there's a second line matching PATTERN1
in between the first two (of several) lines matching PATTERN2
that follow the first line matching PATTERN1
– don_crissti
Jun 28 '16 at 20:29
Would it be possible to not print the last PATTERN2?
– Markus Lindberg
Jun 18 '18 at 15:14
Would it be possible to not print the last PATTERN2?
– Markus Lindberg
Jun 18 '18 at 15:14
@MarkusLindberg you should either create some kind of buffering (otherwise, how do you know if it is the last PATTERN2?) or read the file backwards
– fedorqui
Jul 4 '18 at 6:39
@MarkusLindberg you should either create some kind of buffering (otherwise, how do you know if it is the last PATTERN2?) or read the file backwards
– fedorqui
Jul 4 '18 at 6:39
add a comment |
If we told regarding sed
is to much easy to collect nesessary lines then print
sed -n '
/PATTERN1/
:1
$!N
/(PATTERN2).*1/!b1
p
' file
add a comment |
If we told regarding sed
is to much easy to collect nesessary lines then print
sed -n '
/PATTERN1/
:1
$!N
/(PATTERN2).*1/!b1
p
' file
add a comment |
If we told regarding sed
is to much easy to collect nesessary lines then print
sed -n '
/PATTERN1/
:1
$!N
/(PATTERN2).*1/!b1
p
' file
If we told regarding sed
is to much easy to collect nesessary lines then print
sed -n '
/PATTERN1/
:1
$!N
/(PATTERN2).*1/!b1
p
' file
answered Jun 28 '16 at 13:23
CostasCostas
12.7k1129
12.7k1129
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f292573%2fhow-to-print-lines-between-pattern1-and-2nd-match-of-pattern2%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown