Insert multiple lines into a file after specified pattern using shell script
Solution 1
Another sed
,
sed '/cdef/r add.txt' input.txt
input.txt:
abcd
accd
cdef
line
web
add.txt:
line1
line2
line3
line4
Test:
sat:~# sed '/cdef/r add.txt' input.txt
abcd
accd
cdef
line1
line2
line3
line4
line
web
If you want to apply the changes in input.txt
file. Then, use -i
with sed
.
sed -i '/cdef/r add.txt' input.txt
If you want to use a regex as an expression you have to use the -E
tag with sed
.
sed -E '/RegexPattern/r add.txt' input.txt
Solution 2
Using GNU sed
:
sed "/cdef/aline1\nline2\nline3\nline4" input.txt
If you started with:
abcd
accd
cdef
line
web
this would produce:
abcd
accd
cdef
line1
line2
line3
line4
line
web
If you want to save the changes to the file in-place, say:
sed -i "/cdef/aline1\nline2\nline3\nline4" input.txt
Solution 3
sed '/^cdef$/r'<(
echo "line1"
echo "line2"
echo "line3"
echo "line4"
) -i -- input.txt
Solution 4
Using awk
:
awk '/cdef/{print $0 RS "line1" RS "line2" RS "line3" RS "line4";next}1' input.txt
Explanation:
- You find the line you want to insert from using
/.../
- You print the current line using
print $0
-
RS
is built-inawk
variable that is by default set tonew-line
. - You add new lines separated by this variable
-
1
at the end results in printing of every other lines. Usingnext
before it allows us to prevent the current line since you have already printed it usingprint $0
.
$ awk '/cdef/{print $0 RS "line1" RS "line2" RS "line3" RS "line4";next}1' input.txt
abcd
accd
cdef
line1
line2
line3
line4
line
web
To make changes to the file you can do:
awk '...' input.txt > tmp && mv tmp input.txt
Solution 5
Here is a more generic solution based on @rindeal solution which does not work on MacOS/BSD (/r
expects a file):
cat << DOC > input.txt
abc
cdef
line
DOC
$ cat << EOF | sed '/^cdef$/ r /dev/stdin' input.txt
line 1
line 2
EOF
# outputs:
abc
cdef
line 1
line 2
line
This can be used to pipe anything into the file at the given position:
$ date | sed '/^cdef$/ r /dev/stdin' input.txt
# outputs
abc
cdef
Tue Mar 17 10:50:15 CET 2020
line
Also, you could add multiple commands which allows deleting the marker line cdef
:
$ date | sed '/^cdef$/ {
r /dev/stdin
d
}' input.txt
# outputs
abc
Tue Mar 17 10:53:53 CET 2020
line
Related videos on Youtube
user27
Updated on July 08, 2022Comments
-
user27 almost 2 years
I want to insert multiple lines into a file using shell script. Let us consider my input file contents are: input.txt:
abcd accd cdef line web
Now I have to insert four lines after the line 'cdef' in the input.txt file. After inserting my file should change like this:
abcd accd cdef line1 line2 line3 line4 line web
The above insertion I should do using the shell script. Can any one help me?
-
Sina over 9 yearsIs there a way to do this the other way around (remove text found in add.txt from input.txt) ?
-
hdl over 8 yearsI am new to
sed
but wow I am in love with its power! If you want to append an empty newline first you have to escape the backslash character after the append command like this :sed "/cdef/a\\\nline1\nline2\nline3\nline4" input.txt
. I am not sure why it works like that though, if somebody could explain this would be nice! -
CMCDragonkai over 8 yearsThe current command inserts the line* on every mention of
cdef
, is there a way to make it so that it only inserts on the first time it encounterscdef
and no more? -
Mike Lutz almost 6 yearsMacOS
sed
doesn't implement thea
command precisely the same as GNUsed
, so the above won't work in MacOS without mods - at least as of macOS 10.13 ( see unix.stackexchange.com/a/131940/230763 ) -
potong over 5 yearsA variation, that allows for an anonymous file is to pipe a here document into a sed invocation and use the
r
command to read from/dev/stdin
. -
Walter A over 5 yearsMissed this good answer. Shorter but less readable is
sed '/^cdef$/r' <(printf "%s\n" line{1..4}) -i -- input.txt
. -
Hud over 3 yearsHi, is there a quick way to add 4 spaces before the added lines from
add.txt
? -
Ruli over 3 yearsCan you add some explanation to your command to help the future readers understand what has been done?
-
Luc about 3 years<h1>there is no need to scream</h1>
-
Luc about 3 yearsNote that this won't work in containers when you're issuing the command from the host, as the file descriptor from
<(...)
will be created on the host and not the guest. Using the/someline/a<added\ncontent>
method works better, especially if you do something likesed "/someline/a$(echo 'here you can have newlines' | tr \\n @ | sed '\''s/@/\\n/g'\')" -i -- input.txt
(not a full example and not properly tested, I don't have time for it now, but this should include the building blocks for what you need).