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.
Unless otherwise specified, rules mentioned in the following sections will apply similarly for all the three commands.
The example_files directory has all the files used in the examples.
Basic usage
Just like the substitute command, first letter of these three names represents the command in a sed
script.
a
appends the given string after the end of line for each matching addressc
changes the entire matching address contents to the given stringi
inserts the given string before the start of line for each 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 a 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, some examples with address ranges.
# append and insert is applied for each matching line in the address range
$ seq 5 | sed '2,4i hi there!'
1
hi there!
2
hi there!
3
hi there!
4
5
# change will replace the entire matching range with the given string
$ seq 5 | sed '2,4c hi there!'
1
hi there!
5
# to change every matching line, use the substitute command instead
$ seq 5 | sed '2,4 s/.*/hi there!/'
1
hi there!
hi there!
hi there!
5
Escape sequences
Similar to replacement strings in the substitute command, you can use escape sequences like \t
and \n
, formats like \xNN
and so on.
$ seq 3 | sed '2c rat\tdog\nwolf'
1
rat dog
wolf
3
$ seq 3 | sed '2a fruit: \x27mango\x27'
1
2
fruit: 'mango'
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 the start of the string.
$ seq 3 | sed '2c\nhi'
1
nhi
3
$ seq 3 | sed '2c\\nhi'
1
hi
3
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 the -e
option or a literal newline character to separate the closing }
.
# 'hi ; 3a bye' will treated as a single string argument
$ seq 4 | sed '2c hi ; 3a bye'
1
hi ; 3a bye
3
4
# } gets treated as part of the argument for append, 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{s/^/*/; a hi
> }'
1
*2
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 the content. To avoid the behavior shown below, process the command output as discussed in the Command substitution section.
$ seq 13 15 | sed '3i'"$(printf 'hi\n123')"
sed: -e expression #1, char 8: missing command
# here, the content after the 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
Note | Description |
---|---|
a | appends the given string after the end of line for each matching address |
c | changes the entire matching address contents to the given string |
i | inserts the given string before the start of line for each 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 the first non-whitespace character after the command letter | |
so, you'll need an extra \ if the string argument starts with an escape sequence | |
-e or literal newline is needed to separate any further commands |
This chapter covered three more sed
commands that work similarly to the substitution command for specific use cases. The string argument to these commands allow escape sequences to be used. If you wish to insert contents from a file literally, then use the commands covered in the next chapter.
Exercises
The exercises directory has all the files used in this section.
1) For the input file addr.txt
, display the third line surrounded by -----
.
$ sed ##### add your solution here
-----
This game is good
-----
2) For the input file addr.txt
, replace all lines starting from a line containing you
till the end of file with a blank line followed by Have a nice day
.
$ sed ##### add your solution here
Hello World
Have a nice day
3) For the input file addr.txt
, replace even numbered lines with ---
.
$ sed ##### add your solution here
Hello World
---
This game is good
---
12345
---