Is there any alternative to the "sed -i" command in Solaris?
Use ed
. It's available on most platforms and it can edit your files in-place.
Since sed
is based on ed
the syntax for replacing patterns is similar:
ed -s infile <<\IN
,s/old/new/g
w
q
IN
If you cannot install GNU sed, use:
sed "s/foo/fooofoo/g" abc.txt >abc.tmp && mv abc.tmp abc.txt
This uses redirection to send the output of sed to a temporary file. If sed completes successfully, then this overwrites abc.txt
with the temporary file.
As can be seen from the source code for GNU sed, this is exactly what sed -i
does. So, this is just about as efficient as sed -i
.
If there is a chance that abc.tmp
already exists, then you may want to use mktemp
or a similar utility to generate the unique name for the temporary.
If you want the equivalent of sed -i.bak
, it's pretty simple.
Consider this script for GNU sed:
#!/bin/sh
# Create an input file to demonstrate
trap 'rm -r "$dir"' EXIT
dir=$(mktemp -d)
grep -v '[[:upper:][:punct:]]' /usr/share/dict/words | head >"$dir/foo"
# sed program - removes 'aardvark' and 'aardvarks'
script='/aard/d'
##########
# What we want to do
sed -i.bak -e "$script" "$dir"
##########
# Prove that it worked
ls "$dir"
cat "$dir/foo"
We can simply replace the marked line with
cp "$dir/foo" "$dir/foo.bak" && sed -e "$script" "$dir/foo.bak" >"$dir/foo"
This moves the existing file to be a backup, and writes a new file.
If we want the equivalent of
sed -i -e "$script" "$dir" # no backup
then it's slightly more complex. We can open the file for reading as standard input, then unlink it, before directing sed's output to replace it:
( cp "$dir/foo" "$dir/foo.bak"; exec <"$dir/foo.bak"; rm "$dir/foo.bak"; exec sed -e "$script" >"$dir/foo" )
We do this in a sub-shell, so that our original stdin is still available after this. It's possible to switch inputs and switch back without a subshell, but this way seems clearer to me.
Note that we're careful to copy first, rather than creating a new foo
file - this is important if the file is known by more than one name (i.e. has hard links) and you want to be sure that you don't break the links.