4

I would like to append the contents of a multi-line text file after a particular line in a string. For example, if the file file.txt contains

line 1
line 2

I'd like do so something like printf "s1random stuff\ns2 more random stuff\ns1 final random stuff\n" | sed "/(^s2.+)/a $(<file.txt)"

To get the output:

s1 random stuff
s2 more random stuff
line 1
line 2
s1 final random stuff

I've tried various combinations of quotes and escape characters, but nothing really seems to work. In my particular use case, the string will be a bash variable, so if there's some esoteric thing that that makes that easier it'd be good to know.

What I've got right now that works is writing the string to a file, using grep to find the line I'd like to append after and then using a combination of head, printf, and tail to squish the file together. It just seems like I shouldn't have to write the text to a file to make this work.

3
  • The a command requires a backslash before newlines in the text to be added, because the first unescaped newline ends the command. And also a backslash before the text.
    – Barmar
    Commented Jan 20, 2015 at 20:45
  • That is consistent with the errors I'm getting. Commented Jan 20, 2015 at 20:47
  • 5
    If you have GNU sed you could use the r command to read the file directly e.g. sed '/^s2/ r file.txt' Commented Jan 20, 2015 at 20:48

3 Answers 3

5

Note that you don't have to read the file beforehand, sed has the r command that can read a file:

$ printf -v var "%s\n" "s1random stuff" "s2 more random stuff" "s1 final random stuff"

$ echo "$var"
s1random stuff
s2 more random stuff
s1 final random stuff

$ sed '/^s2/r file.txt' <<< "$var"
s1random stuff
s2 more random stuff
line 1
line 2
s1 final random stuff
4

You need to replace the newlines in the variable with \newline. And the text to be inserted needs to be preceded by \newline.

var=$(<file.txt)
# Put backslash before newlines in $var
var=${var//
/\\
}
printf "s1random stuff\ns2 more random stuff\ns1 final random stuff\n" | sed "/^s2/a \
$var"
0

Are you trying to do something like this?:

LINE1=`cat test.file | sed '1!d'`
LINE2=`cat test.file | sed '2!d'`
LINE3=`cat test.file | sed '3!d'`
LINE4=`cat test.file | sed '4!d'`

echo $LINE1
echo $LINE2
1
  • No. That just spits out the nth line of the file. I want to insert the entire contents of a file right after a line identified by a regex. Commented Jan 20, 2015 at 20:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .