In the examples presented in previous chapter, the output from
sed was displayed on the terminal or redirected to another file. This chapter will discuss how to write back the changes to the input file(s) itself using the
-i command line option. This option can be configured to make changes to the input file(s) with or without creating a backup of original contents. When backups are needed, the original filename can get a prefix or a suffix or both. And the backups can be placed in the same directory or some other directory as needed.
When an extension is provided as an argument to
-i option, the original contents of the input file gets preserved as per the extension given. For example, if the input file is
-i.orig is used, the backup file will be named as
$ cat colors.txt deep blue light orange blue delight $ # no output on terminal as -i option is used $ # space is NOT allowed between -i and extension $ sed -i.bkp 's/blue/green/' colors.txt $ # output from sed is written back to 'colors.txt' $ cat colors.txt deep green light orange green delight $ # original file is preserved in 'colors.txt.bkp' $ cat colors.txt.bkp deep blue light orange blue delight
Sometimes backups are not desirable. Using
-i option on its own will prevent creating backups. Be careful though, as changes made cannot be undone. In such cases, test the command with sample input before using
-i option on actual file. You could also use the option with backup, compare the differences with a
diff program and then delete the backup.
$ cat fruits.txt banana papaya mango $ sed -i 's/an/AN/g' fruits.txt $ cat fruits.txt bANANa papaya mANgo
Multiple input files are treated individually and the changes are written back to respective files.
$ cat f1.txt have a nice day bad morning what a pleasant evening $ cat f2.txt worse than ever too bad $ sed -i.bkp 's/bad/good/' f1.txt f2.txt $ ls f?.* f1.txt f1.txt.bkp f2.txt f2.txt.bkp $ cat f1.txt have a nice day good morning what a pleasant evening $ cat f2.txt worse than ever too good
* character in the argument to
-i option is special. It will get replaced with the input filename. This is helpful if you need to use a prefix instead of suffix for the backup filename. Or any other combination that may be needed.
$ ls *colors* colors.txt colors.txt.bkp $ # single quotes is used here as * is a special shell character $ sed -i'bkp.*' 's/green/yellow/' colors.txt $ ls *colors* bkp.colors.txt colors.txt colors.txt.bkp
* trick can also be used to place the backups in another directory instead of the parent directory of input files. The backup directory should already exist for this to work.
$ mkdir backups $ sed -i'backups/*' 's/good/nice/' f1.txt f2.txt $ ls backups/ f1.txt f2.txt
|after processing, write back changes to the source file(s)|
|changes made cannot be undone, so use this option with caution|
|in addition to in-place editing, preserve original contents to a file|
|whose name is derived from input filename and |
|thus providing a way to add a prefix instead of a suffix|
|this will place the backup copy in a different existing directory|
|instead of source directory|
This chapter discussed about the
-i option which is useful when you need to edit a file in-place. This is particularly useful in automation scripts. But, do ensure that you have tested the
sed command before applying to actual files if you need to use this option without creating backups. In the next chapter, you'll learn filtering features of
sed and how that helps to apply commands to only certain input lines instead of all the lines.
a) For the input file
text.txt, replace all occurrences of
an and write back the changes to
text.txt itself. The original contents should get saved to
$ cat text.txt can ran want plant tin fin fit mine line $ sed ##### add your solution here $ cat text.txt can ran want plant tan fan fit mane lane $ cat text.txt.orig can ran want plant tin fin fit mine line
b) For the input file
text.txt, replace all occurrences of
in and write back the changes to
text.txt itself. Do not create backups for this exercise. Note that you should have solved the previous exercise before starting this one.
$ cat text.txt can ran want plant tan fan fit mane lane $ sed ##### add your solution here $ cat text.txt cin rin wint plint tin fin fit mine line $ diff text.txt text.txt.orig 1c1 < cin rin wint plint --- > can ran want plant
c) For the input file
copyright: 2018 with
copyright: 2019 and write back the changes to
copyright.txt itself. The original contents should get saved to
$ cat copyright.txt bla bla 2015 bla blah 2018 blah bla bla bla copyright: 2018 $ sed ##### add your solution here $ cat copyright.txt bla bla 2015 bla blah 2018 blah bla bla bla copyright: 2019 $ cat 2018_copyright.txt.bkp bla bla 2015 bla blah 2018 blah bla bla bla copyright: 2018
d) In the code sample shown below, two files are created by redirecting output of
echo command. Then a
sed command is used to edit
b1.txt in-place as well as create a backup named
bkp.b1.txt. Will the
sed command work as expected? If not, why?
$ echo '2 apples' > b1.txt $ echo '5 bananas' > -ibkp.txt $ sed -ibkp.* 's/2/two/' b1.txt