Reputation: 14137
I wonder if there is a sed
-only way to print a range of lines, determined by patterns to be matched, except the one last line matching the end pattern.
Consider following example. I have a file
line 1
line 2
line 3
ABC line 4
+ line 5
+ line 6
+ line 7
line 8
line 9
line 10
line 11
line 12
I want to get everything starting with ABC
(including) and all the lines beginning with a +
:
ABC line 4
+ line 5
+ line 6
+ line 7
I tried it with
sed -n '/ABC/I,/^[^+]/ p' file
but this gives one line too much:
ABC line 4
+ line 5
+ line 6
+ line 7
line 8
What's the easiest way (sed
-only) to leave this last line out?
Upvotes: 2
Views: 4695
Reputation: 58401
This might work for you:
sed '/^ABC/{:a;n;/^\(ABC\|+\)/ba};d' file
EDIT: to allow adjacent ABC
sections.
Upvotes: 2
Reputation: 785128
There might be better ways but I could come up with this sed 1 liner:
sed -rn '/ABC/,/^[^+]/{/(ABC|^\+)/!d;p;}' file
sed -n '/ABC/,/^[^+]/{x;/^$/!p;}' file
sed -n '/ABC/I{h;:A;$!n;/^+/{H;$!bA};g;p;}' file
Upvotes: 5
Reputation: 342363
Well, you have selected your answer. But why aren't you using /^(ABC|\+)/
? Or am i mis-understanding your requirement?
If you want to find those +
lines AFTER a search for ABC is found
awk '/ABC/{f=1;print} f &&/^\+/ { print }' file
This is much simpler to understand than crafting cryptic sed
expressions. When ABC is found, set a flag. When lines starting with + is found and flag is set, print line.
Upvotes: 0
Reputation: 37268
The easiest way (I'll learn something new if anyone can solve this with one call to sed), is to add an extra sed at the end, i.e.
sed -n '/ABC/I,/^[^+]/ p' file | sed '$d'
ABC line 4
+ line 5
+ line 6
+ line 7
Cheating, I know, but that is the beauty of the Unix pipe philosphy. Keep whitiling down your data until you get what you want ;-)
I hope this helps.
Upvotes: 2