sed -i(所定の位置で編集)を使用して移植性を達成するには?

sed -i(所定の位置で編集)を使用して移植性を達成するには?

私はFreeBSDを実行する共有ホストである私のサーバー用のシェルスクリプトを作成しています。また、Linuxを実行しているPCでローカルにテストできるようにしたいです。それで、移植可能な方法で作成しようとしていますが、sedそうする方法はないようです。

私のWebサイトの一部は生成された静的HTMLファイルを使用し、次のsed行は各再生成後に正しいDOCTYPEを挿入します。

sed -i '1s/^/<!DOCTYPE html> \n/' ${file_name.html}

これはLinuxのGNUで動作しますsedが、FreeBSDはsedオプションの後の最初の引数が-iバックアップコピーの拡張であると予想しています。次のようになります。

sed -i '' '1s/^/<!DOCTYPE html> \n/' ${file_name.html}

ただし、GNUはsed式がすぐに続くと予想しています-i。 (改行処理も修正する必要がありますが、これはすでにここ)

もちろん、この変更はスクリプトのサーバーコピーに含めることができますが、そうするとVCSを使用してバージョン管理がめちゃくちゃになります。 sedを使用して完全に移植可能な方法でこれを達成する方法はありますか?

ベストアンサー1

GNU sedは、-i中間スペースなしで同じ引数になければならない.extensionsを受け入れます。この構文はFreeBSD sedでも機能します。

sed -i.bak -e '…' SOMEFILE

FreeBSDでは、-i入力ファイルが複数ある場合でも動作が変わります。つまり、入力ファイルは独立して処理されます(たとえば、$各ファイルの最後の行一致)。そしてこれはBusyBoxでは動作しません。

バックアップファイルを使用したくない場合は、利用可能なsedバージョンを確認してください。

# Assume that sed is either FreeBSD/macOS or GNU
case $(sed --help 2>&1) in
  *GNU*) set sed -i;;
  *) set sed -i '';;
esac
"$@" -e '…' "$file"

または、位置パラメータが壊れないようにするには、関数を定義してください。

case $(sed --help 2>&1) in
  *GNU*) sed_i () { sed -i "$@"; };;
  *) sed_i () { sed -i '' "$@"; };;
esac
sed_i -e '…' "$file"

気にしたくない場合は、Perlを使用してください。

perl -i -pe '…' "$file"

移植可能なスクリプトを作成するために使用しないでください。-iPOSIXにはありません。 sed が後ろで実行する操作を手動で実行します。コードを1行だけ追加する必要があります。

sed -e '…' "$file" >"$file.new"
mv -- "$file.new" "$file"

おすすめ記事