このOSX / BSD / GNU sed回避策が機能しない理由

このOSX / BSD / GNU sed回避策が機能しない理由

したがって、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

バックアップファイルを作成せずに機能します。

どんなアイデアがありますか?

答え1

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、可能であればこれを避けるのが一般的に良い(そして安全な)習慣です。

修正する

以下の説明に従って関数を生成するだけです。同じトラックでは、anはaliasおそらく最短の方法です。

if $darwin; then
    alias sedi="sed -i ''"
else
    alias sedi="sed -i"
fi

使いやすい:

sedi "s/VERSION =.*;/VERSION = \"${lver}\";/g" Version.java

答え2

改行シェル関数を定義しますsed

case "$(uname)" in
    Darwin*) sed () { command sed -i '' "$@"; } ;;
    *)       sed () { command sed -i "$@"; } ;;
esac

関連情報