Remove line containing certain string and the following line
Clash Royale CLAN TAG#URR8PPP
up vote
58
down vote
favorite
I use this
cat foo.txt | sed '/bar/d'
to remove lines containing the string bar
in the file.
I would like however to remove those lines and the line directly after it. Preferably in sed
, awk
or other tool that's available in MinGW32.
It's a kind of reverse of what I can get in grep
with -A
and -B
to print matching lines as well as lines before/after the matched line.
Is there any easy way to achieve it?
text-processing sed awk replace
add a comment |Â
up vote
58
down vote
favorite
I use this
cat foo.txt | sed '/bar/d'
to remove lines containing the string bar
in the file.
I would like however to remove those lines and the line directly after it. Preferably in sed
, awk
or other tool that's available in MinGW32.
It's a kind of reverse of what I can get in grep
with -A
and -B
to print matching lines as well as lines before/after the matched line.
Is there any easy way to achieve it?
text-processing sed awk replace
Just for information: I'm analyzing logs in which entries are two-liners. So I want to find an entry matching the pattern and remove it as well as the next line. Hence I don't need to handle consecutive match lines, but thanks anyway for the completeness of your answers!
â jakub.g
Nov 20 '12 at 9:40
add a comment |Â
up vote
58
down vote
favorite
up vote
58
down vote
favorite
I use this
cat foo.txt | sed '/bar/d'
to remove lines containing the string bar
in the file.
I would like however to remove those lines and the line directly after it. Preferably in sed
, awk
or other tool that's available in MinGW32.
It's a kind of reverse of what I can get in grep
with -A
and -B
to print matching lines as well as lines before/after the matched line.
Is there any easy way to achieve it?
text-processing sed awk replace
I use this
cat foo.txt | sed '/bar/d'
to remove lines containing the string bar
in the file.
I would like however to remove those lines and the line directly after it. Preferably in sed
, awk
or other tool that's available in MinGW32.
It's a kind of reverse of what I can get in grep
with -A
and -B
to print matching lines as well as lines before/after the matched line.
Is there any easy way to achieve it?
text-processing sed awk replace
text-processing sed awk replace
edited Dec 15 '15 at 1:25
Gilles
511k12010141544
511k12010141544
asked Nov 19 '12 at 16:41
jakub.g
88621015
88621015
Just for information: I'm analyzing logs in which entries are two-liners. So I want to find an entry matching the pattern and remove it as well as the next line. Hence I don't need to handle consecutive match lines, but thanks anyway for the completeness of your answers!
â jakub.g
Nov 20 '12 at 9:40
add a comment |Â
Just for information: I'm analyzing logs in which entries are two-liners. So I want to find an entry matching the pattern and remove it as well as the next line. Hence I don't need to handle consecutive match lines, but thanks anyway for the completeness of your answers!
â jakub.g
Nov 20 '12 at 9:40
Just for information: I'm analyzing logs in which entries are two-liners. So I want to find an entry matching the pattern and remove it as well as the next line. Hence I don't need to handle consecutive match lines, but thanks anyway for the completeness of your answers!
â jakub.g
Nov 20 '12 at 9:40
Just for information: I'm analyzing logs in which entries are two-liners. So I want to find an entry matching the pattern and remove it as well as the next line. Hence I don't need to handle consecutive match lines, but thanks anyway for the completeness of your answers!
â jakub.g
Nov 20 '12 at 9:40
add a comment |Â
5 Answers
5
active
oldest
votes
up vote
60
down vote
accepted
If you have GNU sed (so non-embedded Linux or Cygwin):
sed '/bar/,+1 d'
If you have bar
on two consecutive lines, this will delete the second line without analyzing it. For example, if you have a 3-line file bar
/bar
/foo
, the foo
line will stay.
1
+1 for the length :) In my particular example I don't have consecutivebar
s so this one is super easy to remember.
â jakub.g
Nov 20 '12 at 9:30
9
sed '/bar/d'
if you just want to "Remove line containing certain string" and not the next.
â AJP
Apr 2 '17 at 9:55
If I want to remove all the lines after math then?
â Pandya
Feb 7 at 9:24
1
@Pandya That's different. You can use e.g.sed '/math/q'
â Gilles
Feb 7 at 12:44
@Gilles Thanks that worked, but I might have done some mistake and asked the question.
â Pandya
Mar 2 at 15:58
add a comment |Â
up vote
15
down vote
If bar
may occur on consecutive lines, you could do:
awk '/bar/n=2; n n--; next; 1' < infile > outfile
which can be adapted to delete more than 2 lines by changing the 2 above with the number of lines to delete including the matching one.
If not, it's easily done in sed
with @MichaelRollins' solution or:
sed '/bar/,/^/d' < infile > outfile
The other plus in the AWK solution is that I can replace/bar/
with/bar|baz|whatever/
. Insed
that syntax doesn't seem to work.
â jakub.g
Nov 21 '12 at 9:58
add a comment |Â
up vote
12
down vote
I am not fluent in sed, but it is easy to do so in awk:
awk '/bar/getline;next 1' foo.txt
The awk script reads: for a line containing bar, get the next line (getline), then skip all subsequent processing (next). The 1 pattern at the end prints the remaining lines.
Update
As pointed out in the comment, the above solution did not work with consecutive bar
. Here is a revised solution, which takes it into consideration:
awk '/bar/ while (/bar/ && getline>0) ; next 1' foo.txt
We now keep reading to skip all the /bar/ lines.
1
To replicategrep -A
100%, you also need to handle any number of consecutivebar
lines correctly (by removing the whole block and 1 line after).
â jw013
Nov 19 '12 at 17:07
add a comment |Â
up vote
7
down vote
You will want to make use of sed's scripting capabilities to accomplish this.
$ sed -e '/bar/
$!N
d
' sample1.txt
Sample data:
$ cat sample1.txt
foo
bar
biz
baz
buz
The "N" command appends the next line of input into the pattern space. This combined with the line from the pattern match (/bar/) will be the lines that you wish to delete. You can then delete normally with the "d" command.
How do I type a newline in console? Or this is script-only?
â jakub.g
Nov 20 '12 at 9:35
@jakub.g: with GNU sed:sed -e '/bar/N;d' sample1.txt
â Cyrus
Jul 27 '14 at 17:51
add a comment |Â
up vote
2
down vote
If any line immediately following a match should be removed then your sed
program will have to consider consecutive matches. In other words, if you remove a line following a match which also matches, then probably you should remove the line following that as well.
It is implemented simply enough - but you have to look-behind a little.
printf %s\n 0 match 2 match match
5 6 match match match
10 11 12 match 14 15 |
sed -ne'x;/match/!g;//!p;'
0
6
11
12
15
It works by swapping hold and pattern spaces for each line read in - so the last line can be compared to the current each time. So when sed
reads a line it exchanges the contents of its buffers - and the previous line is then the contents of its edit buffer, while the current line is put in hold space.
So sed
checks the previous line for a match to match
, and if its !
not found the two expressions in the function
are run.
sed
will g
et the hold space by overwriting the pattern space - which means the current line is then in both the hold and pattern spaces - and then it will //
check it for a match to its most recently compiled regular expression - match
- and if it does not match
it is p
rinted.
This means a line is only printed if it does not match
and the immediately previous line does not match
. It also foregoes any unnecessary swaps for sequences of match
es.
If you wanted a version that could drop an arbitrary number of lines occurring after a match
it would need a little more work:
printf %s\n 1 2 3 4 match
match match 8
9 10 11 12 13
14 match match
17 18 19 20 21 |
sed -net -e'/match/h;n;//h;//!H;G;s/n/&/5;D;' -ep
...replace the 5 with the number of lines (including the matched line) that you would like to remove...
1
2
3
4
12
13
14
21
add a comment |Â
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
60
down vote
accepted
If you have GNU sed (so non-embedded Linux or Cygwin):
sed '/bar/,+1 d'
If you have bar
on two consecutive lines, this will delete the second line without analyzing it. For example, if you have a 3-line file bar
/bar
/foo
, the foo
line will stay.
1
+1 for the length :) In my particular example I don't have consecutivebar
s so this one is super easy to remember.
â jakub.g
Nov 20 '12 at 9:30
9
sed '/bar/d'
if you just want to "Remove line containing certain string" and not the next.
â AJP
Apr 2 '17 at 9:55
If I want to remove all the lines after math then?
â Pandya
Feb 7 at 9:24
1
@Pandya That's different. You can use e.g.sed '/math/q'
â Gilles
Feb 7 at 12:44
@Gilles Thanks that worked, but I might have done some mistake and asked the question.
â Pandya
Mar 2 at 15:58
add a comment |Â
up vote
60
down vote
accepted
If you have GNU sed (so non-embedded Linux or Cygwin):
sed '/bar/,+1 d'
If you have bar
on two consecutive lines, this will delete the second line without analyzing it. For example, if you have a 3-line file bar
/bar
/foo
, the foo
line will stay.
1
+1 for the length :) In my particular example I don't have consecutivebar
s so this one is super easy to remember.
â jakub.g
Nov 20 '12 at 9:30
9
sed '/bar/d'
if you just want to "Remove line containing certain string" and not the next.
â AJP
Apr 2 '17 at 9:55
If I want to remove all the lines after math then?
â Pandya
Feb 7 at 9:24
1
@Pandya That's different. You can use e.g.sed '/math/q'
â Gilles
Feb 7 at 12:44
@Gilles Thanks that worked, but I might have done some mistake and asked the question.
â Pandya
Mar 2 at 15:58
add a comment |Â
up vote
60
down vote
accepted
up vote
60
down vote
accepted
If you have GNU sed (so non-embedded Linux or Cygwin):
sed '/bar/,+1 d'
If you have bar
on two consecutive lines, this will delete the second line without analyzing it. For example, if you have a 3-line file bar
/bar
/foo
, the foo
line will stay.
If you have GNU sed (so non-embedded Linux or Cygwin):
sed '/bar/,+1 d'
If you have bar
on two consecutive lines, this will delete the second line without analyzing it. For example, if you have a 3-line file bar
/bar
/foo
, the foo
line will stay.
answered Nov 19 '12 at 23:34
Gilles
511k12010141544
511k12010141544
1
+1 for the length :) In my particular example I don't have consecutivebar
s so this one is super easy to remember.
â jakub.g
Nov 20 '12 at 9:30
9
sed '/bar/d'
if you just want to "Remove line containing certain string" and not the next.
â AJP
Apr 2 '17 at 9:55
If I want to remove all the lines after math then?
â Pandya
Feb 7 at 9:24
1
@Pandya That's different. You can use e.g.sed '/math/q'
â Gilles
Feb 7 at 12:44
@Gilles Thanks that worked, but I might have done some mistake and asked the question.
â Pandya
Mar 2 at 15:58
add a comment |Â
1
+1 for the length :) In my particular example I don't have consecutivebar
s so this one is super easy to remember.
â jakub.g
Nov 20 '12 at 9:30
9
sed '/bar/d'
if you just want to "Remove line containing certain string" and not the next.
â AJP
Apr 2 '17 at 9:55
If I want to remove all the lines after math then?
â Pandya
Feb 7 at 9:24
1
@Pandya That's different. You can use e.g.sed '/math/q'
â Gilles
Feb 7 at 12:44
@Gilles Thanks that worked, but I might have done some mistake and asked the question.
â Pandya
Mar 2 at 15:58
1
1
+1 for the length :) In my particular example I don't have consecutive
bar
s so this one is super easy to remember.â jakub.g
Nov 20 '12 at 9:30
+1 for the length :) In my particular example I don't have consecutive
bar
s so this one is super easy to remember.â jakub.g
Nov 20 '12 at 9:30
9
9
sed '/bar/d'
if you just want to "Remove line containing certain string" and not the next.â AJP
Apr 2 '17 at 9:55
sed '/bar/d'
if you just want to "Remove line containing certain string" and not the next.â AJP
Apr 2 '17 at 9:55
If I want to remove all the lines after math then?
â Pandya
Feb 7 at 9:24
If I want to remove all the lines after math then?
â Pandya
Feb 7 at 9:24
1
1
@Pandya That's different. You can use e.g.
sed '/math/q'
â Gilles
Feb 7 at 12:44
@Pandya That's different. You can use e.g.
sed '/math/q'
â Gilles
Feb 7 at 12:44
@Gilles Thanks that worked, but I might have done some mistake and asked the question.
â Pandya
Mar 2 at 15:58
@Gilles Thanks that worked, but I might have done some mistake and asked the question.
â Pandya
Mar 2 at 15:58
add a comment |Â
up vote
15
down vote
If bar
may occur on consecutive lines, you could do:
awk '/bar/n=2; n n--; next; 1' < infile > outfile
which can be adapted to delete more than 2 lines by changing the 2 above with the number of lines to delete including the matching one.
If not, it's easily done in sed
with @MichaelRollins' solution or:
sed '/bar/,/^/d' < infile > outfile
The other plus in the AWK solution is that I can replace/bar/
with/bar|baz|whatever/
. Insed
that syntax doesn't seem to work.
â jakub.g
Nov 21 '12 at 9:58
add a comment |Â
up vote
15
down vote
If bar
may occur on consecutive lines, you could do:
awk '/bar/n=2; n n--; next; 1' < infile > outfile
which can be adapted to delete more than 2 lines by changing the 2 above with the number of lines to delete including the matching one.
If not, it's easily done in sed
with @MichaelRollins' solution or:
sed '/bar/,/^/d' < infile > outfile
The other plus in the AWK solution is that I can replace/bar/
with/bar|baz|whatever/
. Insed
that syntax doesn't seem to work.
â jakub.g
Nov 21 '12 at 9:58
add a comment |Â
up vote
15
down vote
up vote
15
down vote
If bar
may occur on consecutive lines, you could do:
awk '/bar/n=2; n n--; next; 1' < infile > outfile
which can be adapted to delete more than 2 lines by changing the 2 above with the number of lines to delete including the matching one.
If not, it's easily done in sed
with @MichaelRollins' solution or:
sed '/bar/,/^/d' < infile > outfile
If bar
may occur on consecutive lines, you could do:
awk '/bar/n=2; n n--; next; 1' < infile > outfile
which can be adapted to delete more than 2 lines by changing the 2 above with the number of lines to delete including the matching one.
If not, it's easily done in sed
with @MichaelRollins' solution or:
sed '/bar/,/^/d' < infile > outfile
edited Apr 13 '17 at 12:36
Communityâ¦
1
1
answered Nov 19 '12 at 20:10
Stéphane Chazelas
286k53528867
286k53528867
The other plus in the AWK solution is that I can replace/bar/
with/bar|baz|whatever/
. Insed
that syntax doesn't seem to work.
â jakub.g
Nov 21 '12 at 9:58
add a comment |Â
The other plus in the AWK solution is that I can replace/bar/
with/bar|baz|whatever/
. Insed
that syntax doesn't seem to work.
â jakub.g
Nov 21 '12 at 9:58
The other plus in the AWK solution is that I can replace
/bar/
with /bar|baz|whatever/
. In sed
that syntax doesn't seem to work.â jakub.g
Nov 21 '12 at 9:58
The other plus in the AWK solution is that I can replace
/bar/
with /bar|baz|whatever/
. In sed
that syntax doesn't seem to work.â jakub.g
Nov 21 '12 at 9:58
add a comment |Â
up vote
12
down vote
I am not fluent in sed, but it is easy to do so in awk:
awk '/bar/getline;next 1' foo.txt
The awk script reads: for a line containing bar, get the next line (getline), then skip all subsequent processing (next). The 1 pattern at the end prints the remaining lines.
Update
As pointed out in the comment, the above solution did not work with consecutive bar
. Here is a revised solution, which takes it into consideration:
awk '/bar/ while (/bar/ && getline>0) ; next 1' foo.txt
We now keep reading to skip all the /bar/ lines.
1
To replicategrep -A
100%, you also need to handle any number of consecutivebar
lines correctly (by removing the whole block and 1 line after).
â jw013
Nov 19 '12 at 17:07
add a comment |Â
up vote
12
down vote
I am not fluent in sed, but it is easy to do so in awk:
awk '/bar/getline;next 1' foo.txt
The awk script reads: for a line containing bar, get the next line (getline), then skip all subsequent processing (next). The 1 pattern at the end prints the remaining lines.
Update
As pointed out in the comment, the above solution did not work with consecutive bar
. Here is a revised solution, which takes it into consideration:
awk '/bar/ while (/bar/ && getline>0) ; next 1' foo.txt
We now keep reading to skip all the /bar/ lines.
1
To replicategrep -A
100%, you also need to handle any number of consecutivebar
lines correctly (by removing the whole block and 1 line after).
â jw013
Nov 19 '12 at 17:07
add a comment |Â
up vote
12
down vote
up vote
12
down vote
I am not fluent in sed, but it is easy to do so in awk:
awk '/bar/getline;next 1' foo.txt
The awk script reads: for a line containing bar, get the next line (getline), then skip all subsequent processing (next). The 1 pattern at the end prints the remaining lines.
Update
As pointed out in the comment, the above solution did not work with consecutive bar
. Here is a revised solution, which takes it into consideration:
awk '/bar/ while (/bar/ && getline>0) ; next 1' foo.txt
We now keep reading to skip all the /bar/ lines.
I am not fluent in sed, but it is easy to do so in awk:
awk '/bar/getline;next 1' foo.txt
The awk script reads: for a line containing bar, get the next line (getline), then skip all subsequent processing (next). The 1 pattern at the end prints the remaining lines.
Update
As pointed out in the comment, the above solution did not work with consecutive bar
. Here is a revised solution, which takes it into consideration:
awk '/bar/ while (/bar/ && getline>0) ; next 1' foo.txt
We now keep reading to skip all the /bar/ lines.
edited Nov 19 '12 at 17:46
answered Nov 19 '12 at 17:03
Hai Vu
90148
90148
1
To replicategrep -A
100%, you also need to handle any number of consecutivebar
lines correctly (by removing the whole block and 1 line after).
â jw013
Nov 19 '12 at 17:07
add a comment |Â
1
To replicategrep -A
100%, you also need to handle any number of consecutivebar
lines correctly (by removing the whole block and 1 line after).
â jw013
Nov 19 '12 at 17:07
1
1
To replicate
grep -A
100%, you also need to handle any number of consecutive bar
lines correctly (by removing the whole block and 1 line after).â jw013
Nov 19 '12 at 17:07
To replicate
grep -A
100%, you also need to handle any number of consecutive bar
lines correctly (by removing the whole block and 1 line after).â jw013
Nov 19 '12 at 17:07
add a comment |Â
up vote
7
down vote
You will want to make use of sed's scripting capabilities to accomplish this.
$ sed -e '/bar/
$!N
d
' sample1.txt
Sample data:
$ cat sample1.txt
foo
bar
biz
baz
buz
The "N" command appends the next line of input into the pattern space. This combined with the line from the pattern match (/bar/) will be the lines that you wish to delete. You can then delete normally with the "d" command.
How do I type a newline in console? Or this is script-only?
â jakub.g
Nov 20 '12 at 9:35
@jakub.g: with GNU sed:sed -e '/bar/N;d' sample1.txt
â Cyrus
Jul 27 '14 at 17:51
add a comment |Â
up vote
7
down vote
You will want to make use of sed's scripting capabilities to accomplish this.
$ sed -e '/bar/
$!N
d
' sample1.txt
Sample data:
$ cat sample1.txt
foo
bar
biz
baz
buz
The "N" command appends the next line of input into the pattern space. This combined with the line from the pattern match (/bar/) will be the lines that you wish to delete. You can then delete normally with the "d" command.
How do I type a newline in console? Or this is script-only?
â jakub.g
Nov 20 '12 at 9:35
@jakub.g: with GNU sed:sed -e '/bar/N;d' sample1.txt
â Cyrus
Jul 27 '14 at 17:51
add a comment |Â
up vote
7
down vote
up vote
7
down vote
You will want to make use of sed's scripting capabilities to accomplish this.
$ sed -e '/bar/
$!N
d
' sample1.txt
Sample data:
$ cat sample1.txt
foo
bar
biz
baz
buz
The "N" command appends the next line of input into the pattern space. This combined with the line from the pattern match (/bar/) will be the lines that you wish to delete. You can then delete normally with the "d" command.
You will want to make use of sed's scripting capabilities to accomplish this.
$ sed -e '/bar/
$!N
d
' sample1.txt
Sample data:
$ cat sample1.txt
foo
bar
biz
baz
buz
The "N" command appends the next line of input into the pattern space. This combined with the line from the pattern match (/bar/) will be the lines that you wish to delete. You can then delete normally with the "d" command.
edited Dec 16 '15 at 10:59
don_crissti
47.4k15126155
47.4k15126155
answered Nov 19 '12 at 18:03
Michael Rollins
811
811
How do I type a newline in console? Or this is script-only?
â jakub.g
Nov 20 '12 at 9:35
@jakub.g: with GNU sed:sed -e '/bar/N;d' sample1.txt
â Cyrus
Jul 27 '14 at 17:51
add a comment |Â
How do I type a newline in console? Or this is script-only?
â jakub.g
Nov 20 '12 at 9:35
@jakub.g: with GNU sed:sed -e '/bar/N;d' sample1.txt
â Cyrus
Jul 27 '14 at 17:51
How do I type a newline in console? Or this is script-only?
â jakub.g
Nov 20 '12 at 9:35
How do I type a newline in console? Or this is script-only?
â jakub.g
Nov 20 '12 at 9:35
@jakub.g: with GNU sed:
sed -e '/bar/N;d' sample1.txt
â Cyrus
Jul 27 '14 at 17:51
@jakub.g: with GNU sed:
sed -e '/bar/N;d' sample1.txt
â Cyrus
Jul 27 '14 at 17:51
add a comment |Â
up vote
2
down vote
If any line immediately following a match should be removed then your sed
program will have to consider consecutive matches. In other words, if you remove a line following a match which also matches, then probably you should remove the line following that as well.
It is implemented simply enough - but you have to look-behind a little.
printf %s\n 0 match 2 match match
5 6 match match match
10 11 12 match 14 15 |
sed -ne'x;/match/!g;//!p;'
0
6
11
12
15
It works by swapping hold and pattern spaces for each line read in - so the last line can be compared to the current each time. So when sed
reads a line it exchanges the contents of its buffers - and the previous line is then the contents of its edit buffer, while the current line is put in hold space.
So sed
checks the previous line for a match to match
, and if its !
not found the two expressions in the function
are run.
sed
will g
et the hold space by overwriting the pattern space - which means the current line is then in both the hold and pattern spaces - and then it will //
check it for a match to its most recently compiled regular expression - match
- and if it does not match
it is p
rinted.
This means a line is only printed if it does not match
and the immediately previous line does not match
. It also foregoes any unnecessary swaps for sequences of match
es.
If you wanted a version that could drop an arbitrary number of lines occurring after a match
it would need a little more work:
printf %s\n 1 2 3 4 match
match match 8
9 10 11 12 13
14 match match
17 18 19 20 21 |
sed -net -e'/match/h;n;//h;//!H;G;s/n/&/5;D;' -ep
...replace the 5 with the number of lines (including the matched line) that you would like to remove...
1
2
3
4
12
13
14
21
add a comment |Â
up vote
2
down vote
If any line immediately following a match should be removed then your sed
program will have to consider consecutive matches. In other words, if you remove a line following a match which also matches, then probably you should remove the line following that as well.
It is implemented simply enough - but you have to look-behind a little.
printf %s\n 0 match 2 match match
5 6 match match match
10 11 12 match 14 15 |
sed -ne'x;/match/!g;//!p;'
0
6
11
12
15
It works by swapping hold and pattern spaces for each line read in - so the last line can be compared to the current each time. So when sed
reads a line it exchanges the contents of its buffers - and the previous line is then the contents of its edit buffer, while the current line is put in hold space.
So sed
checks the previous line for a match to match
, and if its !
not found the two expressions in the function
are run.
sed
will g
et the hold space by overwriting the pattern space - which means the current line is then in both the hold and pattern spaces - and then it will //
check it for a match to its most recently compiled regular expression - match
- and if it does not match
it is p
rinted.
This means a line is only printed if it does not match
and the immediately previous line does not match
. It also foregoes any unnecessary swaps for sequences of match
es.
If you wanted a version that could drop an arbitrary number of lines occurring after a match
it would need a little more work:
printf %s\n 1 2 3 4 match
match match 8
9 10 11 12 13
14 match match
17 18 19 20 21 |
sed -net -e'/match/h;n;//h;//!H;G;s/n/&/5;D;' -ep
...replace the 5 with the number of lines (including the matched line) that you would like to remove...
1
2
3
4
12
13
14
21
add a comment |Â
up vote
2
down vote
up vote
2
down vote
If any line immediately following a match should be removed then your sed
program will have to consider consecutive matches. In other words, if you remove a line following a match which also matches, then probably you should remove the line following that as well.
It is implemented simply enough - but you have to look-behind a little.
printf %s\n 0 match 2 match match
5 6 match match match
10 11 12 match 14 15 |
sed -ne'x;/match/!g;//!p;'
0
6
11
12
15
It works by swapping hold and pattern spaces for each line read in - so the last line can be compared to the current each time. So when sed
reads a line it exchanges the contents of its buffers - and the previous line is then the contents of its edit buffer, while the current line is put in hold space.
So sed
checks the previous line for a match to match
, and if its !
not found the two expressions in the function
are run.
sed
will g
et the hold space by overwriting the pattern space - which means the current line is then in both the hold and pattern spaces - and then it will //
check it for a match to its most recently compiled regular expression - match
- and if it does not match
it is p
rinted.
This means a line is only printed if it does not match
and the immediately previous line does not match
. It also foregoes any unnecessary swaps for sequences of match
es.
If you wanted a version that could drop an arbitrary number of lines occurring after a match
it would need a little more work:
printf %s\n 1 2 3 4 match
match match 8
9 10 11 12 13
14 match match
17 18 19 20 21 |
sed -net -e'/match/h;n;//h;//!H;G;s/n/&/5;D;' -ep
...replace the 5 with the number of lines (including the matched line) that you would like to remove...
1
2
3
4
12
13
14
21
If any line immediately following a match should be removed then your sed
program will have to consider consecutive matches. In other words, if you remove a line following a match which also matches, then probably you should remove the line following that as well.
It is implemented simply enough - but you have to look-behind a little.
printf %s\n 0 match 2 match match
5 6 match match match
10 11 12 match 14 15 |
sed -ne'x;/match/!g;//!p;'
0
6
11
12
15
It works by swapping hold and pattern spaces for each line read in - so the last line can be compared to the current each time. So when sed
reads a line it exchanges the contents of its buffers - and the previous line is then the contents of its edit buffer, while the current line is put in hold space.
So sed
checks the previous line for a match to match
, and if its !
not found the two expressions in the function
are run.
sed
will g
et the hold space by overwriting the pattern space - which means the current line is then in both the hold and pattern spaces - and then it will //
check it for a match to its most recently compiled regular expression - match
- and if it does not match
it is p
rinted.
This means a line is only printed if it does not match
and the immediately previous line does not match
. It also foregoes any unnecessary swaps for sequences of match
es.
If you wanted a version that could drop an arbitrary number of lines occurring after a match
it would need a little more work:
printf %s\n 1 2 3 4 match
match match 8
9 10 11 12 13
14 match match
17 18 19 20 21 |
sed -net -e'/match/h;n;//h;//!H;G;s/n/&/5;D;' -ep
...replace the 5 with the number of lines (including the matched line) that you would like to remove...
1
2
3
4
12
13
14
21
edited Dec 16 '15 at 6:39
answered Dec 15 '15 at 2:08
mikeserv
44.5k565150
44.5k565150
add a comment |Â
add a comment |Â
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
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f56123%2fremove-line-containing-certain-string-and-the-following-line%23new-answer', 'question_page');
);
Post as a guest
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
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
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
Just for information: I'm analyzing logs in which entries are two-liners. So I want to find an entry matching the pattern and remove it as well as the next line. Hence I don't need to handle consecutive match lines, but thanks anyway for the completeness of your answers!
â jakub.g
Nov 20 '12 at 9:40