0

I would like to insert the contents of one text file (with newlines) into another at a predetermined location (after some string): I tried the following: the base file:

cat base
ONE
TWO
THREE

the extension:

cat ext
100
200
300
400
500
600
700
800
900
A00
B00
C00
D00

and the script I tried:

#!/bin/bash
ext=$(<ext)
sed -i "s/TWO/TWO\n$ext/" base

which gives me sed: -e expression #1, char 14: unterminated `s' command

Testix
  • 113
  • 1
  • 7

3 Answers3

3

If you want to edit a file directly, I always suggest ed instead of the non-standard sed -i (Where different implementions of sed that do support it act differently, a common source of questions here):

printf "%s\n" "/TWO/r ext" w | ed -s base

will insert the contents of file ext after the first line containing TWO in base, and then write the new version of base back to disk.

If you must use sed, the proper invocation will look very similar (No surprise since they're sibling commands):

sed -i '/TWO/r ext' base

(This will insert the ext file after every TWO in base, though, not just the first.)

The key in both is the r command, which reads the contents of the given file and inserts it after a line with the matching address. Works a lot better than trying to read the file contents into a variable and including the text directly in the ed/sed commands.


If you want to insert the contents of a variable after the line, you can use

printf "%s\n" "/TWO/a" "$ext" . w | ed -s base

(As long as the variable doesn't have a line with just a period)

or with GNU sed

sed -i "/TWO/a ${ext//$'\n'/\\\n}" base

to append text after the addressed line.

Shawn
  • 47,241
  • 3
  • 26
  • 60
0

While the answer given by Shawn shows a possible solution, it does not explain why your attempt did not work.

Note that your variable ext contains line feed characters. Hence, sed sees here a physical line feed. You would get the same error message when typing on the command line (in two lines):

sed -i "s/TWO/TWO\nfoo
/" base
user1934428
  • 19,864
  • 7
  • 42
  • 87
0

This might work for you (GNU sed):

sed -e '0,/TWO/{/TWO/r extFile' -e '}' baseFile

This will place the file extFile after the first occurrence of the string TWO. The -i option may be used to amend the file in place.

An alternative solution:

sed -e '/TWO/!b;r extFile' -e ':a;n;ba' baseFile

N.B. The use of the -e option to split the commands after the r filename command. The r must be followed by a newline and the -e simulates this on a single line.

If you want to insert the file after each occurrence of the string TWO, then just use (as Shawn has already explained):

sed '/TWO/r extFile' baseFile
potong
  • 55,640
  • 6
  • 51
  • 83