For sed 's/cat/dog/'
or any other substitution that doesn't change the size of the file, with any Bourne-like shell, you can do:
sed 's/cat/dog/' < file 1<> file
The little-known but over 35 year old¹ standard <>
operator is to open a file in read+write mode without truncation. Basically, here that makes sed
write its output over its input. It's important to make sure that the output doesn't overwrite sections of the file that sed
has not read yet.
For substitutions that cause the file size to decrease, with ksh93
:
sed 's/hippopotamus/ant/' < file 1<>; file
<>;
, a ksh93
extension is the same as <>
except that if the command being redirected succeeds, the file gets truncated where the command finished.
Or with perl:
perl -pe 's/hippopotamus/ant/;
END{truncate STDOUT, tell STDOUT}' < file 1<> file
For anything else, just use the standard form:
cp -i file file.back &&
sed 's/dog/horse/g' < file.back > file # && rm -f file.back
¹ Though the initial implementation in the Bourne shell and early versions of the Korn shell was actually broken, fixed in the late 80s. And the Almquist shell initially didn't support it.