Sed receives text input, either from stdin or from a file, performs certain operations on specified lines(or all lines) of the input, one line at a time, then outputs the result to stdout or to a file. Today I am going to show how we can use sed to do some operation on a file (mainly substitute, which is the most popular with sed) and write back the results to the same file.
Input file:
$ cat file.txt
port:9903
os-version:VERSION
codename:hardy
status:active
Lets try to replace the word 'VERSION' in the above file with '8.04'
$ sed 's/VERSION/8.04/' file.txt
port:9903
os-version:8.04
codename:hardy
status:active
So, be default sed outputs the result to 'stdout'.
Append or redirection to the same filename will be wrong !!
$ sed 's/VERSION/8.04/' file.txt > file.txt
Newer sed versions (e.g sed version 4.1.4), there is a useful command line option:
-i[SUFFIX], --in-place[=SUFFIX]
Description: edit files in place (makes backup if extension supplied)
Lets try this option:
$ cat file.txt
port:9903
os-version:VERSION
codename:hardy
status:active
$ sed -i 's/VERSION/8.04/' file.txt
$ cat file.txt
port:9903
os-version:8.04
codename:hardy
status:active
It worked; the result is printed to the same filename.
We can also mention the backup extension like this:
$ cat file.txt
port:9903
os-version:VERSION
codename:hardy
status:active
$ sed -i.bak 's/VERSION/8.04/' file.txt
$ cat file.txt
port:9903
os-version:8.04
codename:hardy
status:active
The original content of the input file is backed up here:
$ cat file.txt.bak
port:9903
os-version:VERSION
codename:hardy
status:active
With older version of 'sed' editor (where this -i option is absent), we can write the result to a temporary file and then in the next step we can move the temporary file back to the original file like this:
$ cat file.txt
port:9903
os-version:VERSION
codename:hardy
status:active
$ sed 's/VERSION/8.04/' file.txt > file.txt.tmp
$ mv file.txt.tmp file.txt
And to work with more number of files (say perform the same replacement as above in all the .cfg files in current directory, including sub-directory)
for file in $(find . -name "*.cfg")
do
echo "Replacing on : $file"
sed 's/VERSION/8.04/' $file > $file.tmp
mv $file.tmp $file
echo "Replacement done on : $file"
done
Related posts:
- Add Change Insert lines to file using sed
- Substitute character by position using sed
- Case insensitive search and replace using sed
- Accessing external variables in sed and awk
- Delete next few lines using sed

3 comments:
Hey, nice blog, I get a lot of enjoyment out of reading random snippets like these.
I noticed you didn't quote $file though:
for file in $(find . -name "*.cfg")
do
echo "Replacing on : $file"
sed 's/VERSION/8.04/' $file > $file.tmp
mv $file.tmp $file
echo "Replacement done on : $file"
done
This will break if $file ever has spaces or other abnormal characters.
probably just an oversight, but hey I'm in the mood to rant...
http://bash-hackers.org/wiki/doku.php/syntax/words
http://www.grymoire.com/Unix/Quote.html
@Stu, thanks for the same.
agreed ... nice to see there are still other command line dweebs out there (aside from me)
Post a Comment