Reputation: 2260
I want to do a basic sed
-line insertion but withing a given line range.
Using given sample file sample.txt
:
foo
tomato
apple
bar
START_MARKER
tomato
apple
kiwifruit
pineapple
strawberry
END_MARKER
apple
qux
I want to add a line (say "_____new_line_____") before any line between "START_MARKER" and "END_MARKER" that contains "apple". My sample would then become:
foo
tomato
apple
bar
START_MARKER
tomato
_____new_line_____
apple
kiwifruit
_____new_line_____
pineapple
strawberry
END_MARKER
apple
qux
I tried:
sed '/^START_MARKER$/,/^END_MARKER$/ /apple/i _____new_line_____' sample.txt
But I get:
sed: -e expression #1, char 33: unknown command: `/'
Also tried:
sed '/^START_MARKER$/,/^END_MARKER$/ {/apple/i _____new_line_____}' sample.txt
But I get:
sed: -e expression #1, char 0: unmatched `{'
If I wanted to add a "_____new_line_____" line before all line containing "apple" (not using START_MARKER and END_MARKER) the following would work:
sed '/apple/i _____new_line_____' sample.txt
I am missing something to chain/combine the /start/,/end/ pattern selection with my //i add-line-operation.
Upvotes: 2
Views: 926
Reputation: 58430
This might work for you (GNU sed):
sed -e '/START/{:a;n;/apple/i\__newline__' -e '/END/!ba}' file
This inserts a line before any line containing apple
between START
and END
or the end of the file.
To insert a line only between START
and END
before a line containing apple
use:
sed -e ':a;/\n/{/^[^\n]*apple/i\__newline__' -e 'P;D};/START/{:b;N;/END/!bb;ba}' file
This gathers up the lines between START
and END
and only then inserts a line before the lines containing apple
.
Upvotes: 0
Reputation: 402
You can use the following:
sed '/START_MARKER/,/END_MARKER/!b;/apple/ i_____new_line_____' sample.txt > out
where sed
goes through every line and if the pattern 'apple' is in the range of START_MARKER and END_MARKER, it inserts '_____new_line_____' before 'apple' and if the pattern 'apple' is not in the range, then it does nothing.
If you don't direct the output to a file then it will print on the terminal screen.
Upvotes: 1
Reputation: 23667
With GNU sed
$ sed -e '/^START_MARKER$/,/^END_MARKER$/ { /apple/i _____new_line_____' -e '}' ip.txt
foo
tomato
apple
bar
START_MARKER
tomato
_____new_line_____
apple
kiwifruit
_____new_line_____
pineapple
strawberry
END_MARKER
apple
qux
Everything after a/c/i
command is considered as the argument for that command. So, you need to separate them using newline or -e
option as shown above. See https://www.gnu.org/software/sed/manual/sed.html#Commands-Requiring-a-newline for more details.
With other sed
, this might work, but not sure as I can't test it:
sed '/^START_MARKER$/,/^END_MARKER$/ {
/apple/i\
_____new_line_____
}' ip.txt
Upvotes: 1