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
    Jan 20, 2015 at 20:45
  • That is consistent with the errors I'm getting. 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' 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. Jan 20, 2015 at 20:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.