How can I achieve portability with sed -i (in-place editing)?
GNU sed accepts an optional extension after -i
. The extension must be in the same argument with no intervening space. This syntax also works on BSD sed.
sed -i.bak -e '…' SOMEFILE
Note that on BSD, -i
also changes the behavior when there are multiple input files: they are processed independently (so e.g. $
matches the last line of each file). Also this won't work on BusyBox.
If you don't want to use backup files, you could check which version of sed is available.
case $(sed --help 2>&1) in
*GNU*) set sed -i;;
*) set sed -i '';;
esac
"$@" -e '…' "$file"
Or alternatively, to avoid clobbering the positional parameters, define a function.
case $(sed --help 2>&1) in
*GNU*) sed_i () { sed -i "$@"; };;
*) sed_i () { sed -i '' "$@"; };;
esac
sed_i -e '…' "$file"
If you don't want to bother, use Perl.
perl -i -pe '…' "$file"
If you want to write a portable script, don't use -i
— it isn't in POSIX. Do manually what sed does under the hood — it's only one more line of code.
sed -e '…' "$file" >"$file.new"
mv -- "$file.new" "$file"
If you don't find a trick to make sed
play nice, you could try:
Don't use
-i
:sed '1s/^/<!DOCTYPE html> \n/' "${file_name.html}" > "${file_name.html}.tmp" && mv "${file_name.html}.tmp" "${file_name.html}"
Use Perl
perl -i -pe 'print "<!DOCTYPE html> \n" if $.==1;' "${file_name.html}"
ed
You can always use ed
to prepend a line to an existing file.
$ printf '0a\n<!DOCTYPE html>\n.\nw\n' | ed my.html
Details
The bits around the <!DOCTYPE html>
are commands to ed
instructing it to add that line to the file my.html
.
sed
I believe this command in sed
can also be used:
$ sed -i '1i<!DOCTYPE html>\n` testfile.csv