したがって、sedは、OSX/BSDバージョンかGNUバージョンか)によって動作が異なります。
OSXには
sed -i '' <pattern> <file>
一方、これはGNU sed:
sed -i <pattern> <file>
だから私はこれを持っています:
darwin=false;
case "$(uname)" in
Darwin*) darwin=true ;;
esac
if $darwin; then
sedi="sed -i '' "
else
sedi="sed -i"
fi
そして、OSXでそれを呼び出そうとします
$sedi "s/VERSION =.*;/VERSION = \"${lver}\";/g" Version.Java
また、Version.Java ''という名前のバックアップファイルを作成する以外は機能します。
CLIから明示的に行うと、なぜこれが機能しないのかわかりません。
sed -i '' "s/VERSION =.*;/VERSION = \"${lver}\";/g" Version.Java
バックアップファイルを作成しなくても機能します。
何かご意見は?
sedi
変数を展開すると、期待どおりに空の引数を作成するのではなく、''
が引数としてsed
に渡されます。
これを回避するための最良の方法は、sedi
変数を配列にすることです。
if $darwin; then
sedi=(sed -i '')
else
sedi=(sed -i)
fi
そして、このように使用します:
"${sedi[@]}" "s/VERSION =.*;/VERSION = \"${lver}\";/g" Version.Java
それ以外の場合、''
を実際の空の引数に変換する唯一の方法は、元の宣言でeval
を使用することだと思います。
eval $sedi '"s/VERSION =.*;/VERSION = \"${lver}\";/g"' Version.Java
ただし、コマンドの残りの部分に引用符/エスケープのレイヤーを追加する必要があるため、これはやや厄介な解決策です。また、可能な場合はeval
の使用を避けることは、一般的に良い(そして安全な)方法です。
以下にコメントするように、関数の作成は機能します。同じトラックで、alias
がおそらく最短の方法です。
if $darwin; then
alias sedi="sed -i ''"
else
alias sedi="sed -i"
fi
簡単に使用する:
sedi "s/VERSION =.*;/VERSION = \"${lver}\";/g" Version.Java
代わりにsed
をラップするシェル関数を定義します。
case "$(uname)" in
Darwin*) sed () { command sed -i '' "$@"; } ;;
*) sed () { command sed -i "$@"; } ;;
esac