FreeBSDを実行している共有ホスティングであるサーバー用のシェルスクリプトを書いています。また、Linuxを実行しているPCで、ローカルでテストできるようにしたいと考えています。したがって、私はそれらを移植可能な方法で書き込もうとしていますが、sed
それをする方法がわかりません。
私のウェブサイトの一部は生成された静的HTMLファイルを使用しており、このsed行は各再生成後に正しいDOCTYPEを挿入します:
sed -i '1s/^/<!DOCTYPE html> n/' ${file_name.html}
GNU sed
で動作します Linuxでは、ただしFreeBSD sed
-i
の後の最初の引数が必要です バックアップコピーの拡張機能となるオプション。これはどのように見えるかです:
sed -i '' '1s/^/<!DOCTYPE html> n/' ${file_name.html}
ただし、GNU sed
次に、式が-i
の直後に続くことを期待します 。
(改行処理による修正も必要ですが、これはすでにここで回答されています)
もちろん、この変更をスクリプトのサーバーコピーに含めることはできますが、それは混乱を招きます。つまり、バージョン管理のためのVCSの使用です。完全にポータブルな方法でsedを使用してこれを実現する方法はありますか?
承認された回答:
GNU sedは、-i
の後にオプションの拡張子を受け入れます 。拡張子は、間にスペースを入れずに同じ引数に含める必要があります。この構文はBSDsedでも機能します。
sed -i.bak -e '…' SOMEFILE
BSDでは、-i
また、複数の入力ファイルがある場合の動作も変更されます。これらは個別に処理されます(たとえば、$
各ファイルの最後の行に一致します)。また、これはBusyBoxでは機能しません。
バックアップファイルを使用したくない場合は、使用可能なsedのバージョンを確認できます。
case $(sed --help 2>&1) in
*GNU*) set sed -i;;
*) set sed -i '';;
esac
"[email protected]" -e '…' "$file"
または、位置パラメータの混乱を避けるために、関数を定義します。
case $(sed --help 2>&1) in
*GNU*) sed_i () { sed -i "[email protected]"; };;
*) sed_i () { sed -i '' "[email protected]"; };;
esac
sed_i -e '…' "$file"
気にしない場合は、Perlを使用してください。
perl -i -pe '…' "$file"
ポータブルスクリプトを作成する場合は、-i
を使用しないでください —POSIXにはありません。 sedが内部で行うことを手動で実行します。これは、あと1行のコードです。
sed -e '…' "$file" >"$file.new"
mv -- "$file.new" "$file"