Reputation: 1722
I was trying to copy an example I found here : http://www.grymoire.com/Unix/Sed.html#uh-35a
here is the sed pattern
/^begin$/,/^end$/{
/begin/n
/end/!d
}
here's the first file
begin
one
end
last line
and here's the second
begin
end
last line
when I run the sed on the first file it deletes what's between the begin/end and all is well. When I run it on the second, it appears to miss the "end" and deletes the rest of the file.
running on first file
$ sed -f x.sed a
begin
end
last line
running on second
$ sed -f x.sed b
begin
end
notice how "last line" is missing on the second run.
I thought that "n" would print the current pattern and suck in the next one. It would then hit the /end/ command and process that.
as it is, it seems like it's somehow causing the end of the range to be missed. Will somebody explain what is happening?
Upvotes: 3
Views: 110
Reputation:
I think you were close to getting it to do what you wanted. When you want to delete the next line after a match you simply need to pull it in with the sed n
and then hit it with a delete d
.
It looks like you want to skip the line after the line that starts with begin
unless it's end
and print all the other lines.
If so, the following should suffice:
/^begin$/,/^end$/{
/begin/{n;/end/!d}
}
It works by skipping the next line after begin except if it starts with end (/end/!
).
Also see: sed or awk: delete n lines following a pattern
Upvotes: 0
Reputation: 1722
found another way around after @hek2mgl 's help. I can add a branch around the 2nd statement. I actually need this because I want to see the begin label. so you can also do this:
/^begin$/,/^end$/{
/begin/{ b skip }
/end/!d
:skip
}
Upvotes: 0
Reputation: 158120
It should be:
/^begin$/,/^end$/{
/^begin$\|^end$/!d
}
Why was your command wrong?
The n
command was wrong there. In the second example it will:
begin
---> n read next line(important: this does not affect the state of the range address (begin,end))
1a. end
---> /end/!
does not apply. Don't delete the line
last line
---> /end/!
applies. Delete the line. (sed
is still searching for a line that contains end
because the n
command skipped that line)
Upvotes: 1