139

Right now I'm using

echo "Hello World" >> file.txt

to append some text to a file but I also need to add text below a certain string let's say [option], is it possible with sed?

EG:

Input file

Some text
Random
[option]
Some stuff

Output file

Some text
Random
[option]
*inserted text*
Some stuff
AdminBee
  • 22,803
  • 2
    You have to be more specific and give some sample text for people to help you with exact commands. – clement Mar 24 '14 at 14:51
  • please edit you Q and show the input and the output lines. Because you Q is unclear. You could also do echo "Hello World [option]" >> file.txt, but it doesn't make sense. –  Mar 24 '14 at 14:56
  • I edited the question to provide more information for reference but the accepted answer was what I was trying to accomplish – Javier Villanueva Mar 24 '14 at 21:25
  • If you just want to edit a config file this is the best solution I found: http://unix.stackexchange.com/a/78076/20661 – rubo77 Jul 21 '16 at 08:20

4 Answers4

173

Append line after match

  • sed '/\[option\]/a Hello World' input

Insert line before match

  • sed '/\[option\]/i Hello World' input

Additionally you can take backup and edit input file in-place using -i.bkp option to sed

Rahul Patil
  • 24,711
  • 8
    on osx i get sed: 1: "/pattern/a some text here": command a expects \ followed by text – the_prole Jan 20 '19 at 21:11
  • @the_prole https://unix.stackexchange.com/questions/229873/how-to-fix-command-a-expects-followed-by-text-in-my-sed – Rahul Patil Jan 21 '19 at 14:45
  • 4
    for Mac OSX, I needed to add \ <<NEWLINE>> after the a option – Tom Howard Aug 02 '19 at 13:34
  • 1
    The above code will append/insert the line for every single match. If you want to append/insert the line for the first match only, you can prepend 0, to the commands: sed '0,/\[option\]/a Hello World' input or sed '0,/\[option\]/i Hello World' input – kimbaudi Aug 07 '19 at 02:50
  • @kimbaudi I'm not sure why, but in my case merely adding 0, inserts the line all over the file without any noticeable pattern (similar to https://stackoverflow.com/q/54382514) – ᴍᴇʜᴏᴠ Aug 11 '20 at 09:37
  • 1
    Works for me and if you want insert space it may like sed '/\[option\]/a \ \ Hello World' input – hukeping Oct 09 '20 at 08:40
  • To save it in the file add the i flag like `sed -i '/match-after-I-put-mystuff/a mystuff' file-with-new-stuff – Timo Nov 01 '20 at 07:42
  • 1
    If the appended string is a multiline text u can save it to a file (e.g.: snippet.txt) and inject this file after the pattern using: sed -i '/pattern/ r snippet.txt' filename – Savrige Oct 24 '21 at 14:40
  • /a does not work for all OS and sed versions. I found the solution which seems to be general, see https://stackoverflow.com/a/69873897/4807875. – Alexander Samoylov Nov 07 '21 at 15:40
54

Yes, it is possible with sed:

sed '/pattern/a some text here' filename

An example:

$ cat test
foo
bar
option
baz
$ sed '/option/a insert text here' test
foo
bar
option
insert text here
baz
$
devnull
  • 10,691
10

With awk:

awk '1;/PATTERN/{ print "add one line"; print "\\and one more"}' infile

Keep in mind that some characters can not be included literally so one has to use escape sequences (they begin with a backslash) e.g. to print a literal backslash one has to write \\.

It's actually the same with sed but in addition each embedded newline in the text has to be preceded by a backslash:

sed '/PATTERN/a\
add one line\
\\and one more' infile

For more details on escape sequences consult the manual.


Also, to address some of the comments: the above commands DO NOT edit the file in place, they just print the result to the standard output. To actually modify the input file you would either use the -i switch if your awk/sed support it (consult the manual) or redirect to a temporary file then overwrite the original e.g.

cmd infile > outfile
mv outfile infile

Or use ed/ex which can edit the files in-place on all platforms:

ex -s infile <<\IN
/PATTERN/a
add one line
and one more
.
w
q
IN

Remember: with ed/sed/ex, a appends and i inserts; with awk, to insert, move the 1 to the end.

don_crissti
  • 82,805
  • An awk line does not actually change the text, only output. – Josef Klimuk Jun 17 '18 at 14:51
  • To change text in a file (replace inline), use awk -i inline ... – Tim Visee Jan 20 '21 at 16:37
  • Notes: to modify a file in-place (and avoid emptying the input file), this awk output should be piped to a file, which should be copied after its done back to the same file; PATTERN should not be surrounded by quotes. – mirekphd Jan 24 '23 at 21:20
1

This can also be achieved using the ed utility. It's easier to use sed but nice to be familiar with an additional utility (I came to this page, specifically looking how to achieve this using ed; I already knew how to do it in sed).

For your example file (printed with line numbers for reference):

 1  Some text
 2  Random
 3  [option]
 4  Some stuff

The ed commands to achieve the suggested output would be:

4i
*inserted text*
.
w
q

Explanation:

  1. go to line 4, start insert mode (i)
  2. add *inserted text* (including the newline)
  3. exit insert mode (.)
  4. write the file (w) and quit ed (q)

You can put this all together in one command using a here string:

ed filename.txt <<< '4i
*inserted text*
.
w
q
'
moo
  • 277