append, change, insert

These three commands come in handy for specific operations as suggested by their names. The substitute command could handle most of the features offered by these commands. But where applicable, these commands would be easier to use.

info Unless otherwise specified, rules mentioned in the following sections will apply similarly for all the three commands.

Basic usage

Just like the substitute command, first letter of these three names represents the command in a sed script.

  • a appends given string after end of line of each of the matching address
  • c changes the entire matching address contents to the given string
  • i inserts given string before start of line of each of the matching address

The string value for these commands is supplied after the command letter. Any whitespace between the letter and the string value is ignored. First up, some examples with single address as the qualifier.

$ # same as: sed '2 s/$/\nhello/'
$ seq 3 | sed '2a hello'
1
2
hello
3

$ # same as: sed '/[24]/ s/.*/hello/'
$ seq 5 | sed '/[24]/c hello'
1
hello
3
hello
5

$ # same as: sed '2 s/^/hello\n/'
$ seq 3 | sed '2i hello'
1
hello
2
3

Next, examples with address ranges.

$ # append and insert will apply for each matching line of address range
$ seq 5 | sed '2,4i hi there!'
1
hi there!
2
hi there!
3
hi there!
4
5

$ # change will replace entire matching range with given string
$ seq 5 | sed '2,4c hi there!'
1
hi there!
5
$ # to change every matching line, use substitute command
$ seq 5 | sed '2,4 s/.*/hi there!/'
1
hi there!
hi there!
hi there!
5

Escape sequences

Similar to replacement strings in substitute command, you can use escape sequences like \t, \n, etc and ASCII value formats like \xNN.

$ seq 3 | sed '2c rat\tdog\nwolf'
1
rat     dog
wolf
3
$ seq 3 | sed '2a it\x27s sunny today'
1
2
it's sunny today
3

As mentioned before, any whitespace between the command and the string is ignored. You can use \ after the command letter to prevent that.

$ seq 3 | sed '2c         hello'
1
hello
3

$ seq 3 | sed '2c\         hello'
1
         hello
3

As \ has another meaning when used immediately after command letter, use an additional \ if there is a normal escape sequence at start of the string.

$ seq 3 | sed '2c\nhi'
1
nhi
3

$ seq 3 | sed '2c\\nhi'
1

hi
3

info See also stackoverflow: add newline character if last line of input doesn't have one

Multiple commands

All the three commands will treat everything after the command letter as the string argument. Thus, you cannot use ; as command separator or # to start a comment. Even command grouping with {} will fail unless you use -e option or literal newline to separate the closing }.

$ # 'hi ; 3a bye' will treated as single string argument
$ seq 4 | sed '2c hi ; 3a bye'
1
hi ; 3a bye
3
4
$ # } gets treated as part of argument for append command, hence the error
$ seq 3 | sed '2{s/^/*/; a hi}'
sed: -e expression #1, char 0: unmatched `{'

$ # use -e or literal newline to separate the commands
$ seq 4 | sed -e '2c hi' -e '3a bye'
1
hi
3
bye
4
$ seq 3 | sed '2{c hi
> }'
1
hi
3

Shell substitution

This section is included in this chapter to showcase more examples for shell substitutions and to warn about the potential pitfalls.

$ # variable substitution
$ text='good\tone\nfood\tpun'
$ seq 13 15 | sed '2c'"$text"
13
good    one
food    pun
15

$ # command substitution
$ seq 13 15 | sed '3i'"$(date +%A)"
13
14
Wednesday
15

Literal newline in the substituted string may cause an error depending upon content. To avoid the behavior shown below, process the command output as discussed in Command substitution section.

$ seq 13 15 | sed '3i'"$(printf 'hi\n123')"
sed: -e expression #1, char 8: missing command

$ # here, the content after newline gets executed as a command
$ # same as: sed -e '3i hi' -e 's/5/five/'
$ seq 13 15 | sed '3i'"$(printf 'hi\ns/5/five/')"
13
14
hi
1five

Cheatsheet and summary

NoteDescription
aappends given string after end of line of each of the matching address
cchanges the entire matching address contents to the given string
iinserts given string before start of line of each of the matching address
string value for these commands is supplied after the command letter
escape sequences like \t, \n, \xNN, etc can be used in the string value
any whitespace between command letter and the string value is ignored
unless \ is used after command letter
\ after command letter is also needed if escape sequence is the first character
-e or literal newline is needed to separate any further commands

This chapter covered three more sed commands that work similarly to substitution command for specific use cases. The string argument to these commands allow escape sequences to be used. If you do not wish the text to be interpreted or if you wish to provide text from a file, then use the commands covered in next chapter, which allows you to add text literally.

Exercises

a) For the input file addr.txt, print only the third line and surround it with -----

$ sed ##### add your solution here
-----
This game is good
-----

b) For the input file addr.txt, replace all lines starting from a line containing you till end of file with content as shown below.

$ sed ##### add your solution here
Hello World

Have a nice day

c) Replace every even numbered line with ---

$ seq 0 5 | sed ##### add your solution here
0
---
2
---
4
---