Reputation: 914
I want to insert multiple lines into a file using shell script. Let us consider my original file: original.txt:
aaa
bbb
ccc
aaa
bbb
ccc
aaa
bbb
ccc
.
.
.
and my insert file: toinsert.txt
111
222
333
Now I have to insert the three lines from the 'toinsert.txt' file ONLY after the line 'ccc' appears for the FIRST time in the 'original.txt' file. Note: the 'ccc' pattern appears more than one time in my 'original.txt' file. After inserting ONLY after the pattern appears for the FIRST time, my file should change like this:
aaa
bbb
ccc
111
222
333
aaa
bbb
ccc
aaa
bbb
ccc
.
.
.
I should do the above insertion using a shell script. Can someone help me?
Note2: I found a similar case, with a partial solution:
sed -i -e '/ccc/r toinsert.txt' original.txt
which actually does the insertion multiple times (for every time the ccc pattern shows up).
Upvotes: 1
Views: 607
Reputation: 58371
This might work for you (GNU sed):
sed '0,/ccc/!b;/ccc/r insertFile' file
Use a range:
If the current line is in the range following the first occurrence of ccc
, break from further processing and implicitly print as usual.
Otherwise if the current line does contain ccc
,insert lines from insertFile
.
N.B. This uses the address 0
which allows the regexp to occur on line 1 and is specific to GNU sed.
or:
sed -e '/ccc/!b;r insertFile' -e ':a;n;ba' file
Use a loop:
If a line does not contain ccc
, no further processing and print as usual.
Otherwise, insert lines from insertFile
and then using a loop, fetch/print the remaining lines until the end of the file.
N.B. The r
command insists on being delimited from other sed commands by a newline. The -e
option simulates this effect and thus the sed commands are split across two -e
options.
or:
sed 'x;/./{x;b};x;/ccc/!b;h;r insertFile' file
Use a flag:
If the hold space is not empty (the flag has already been set), no further processing and print as usual.
Otherwise, if the line does not contain ccc
, no further processing and print as usual.
Otherwise, copy the current line to the hold space (set the flag) and insert lines from insertFile
.
N.B. In all cases the r
command inserts lines from insertFile
after the current line is printed.
Upvotes: 2
Reputation: 52334
Use ed
, not sed
, to edit files:
printf "%s\n" "/ccc/r toinsert.txt" w | ed -s original.txt
It inserts the contents of the other file after the first line containing ccc
, but unlike your sed
version, only after the first.
Upvotes: 3