sedコマンドがインタラクティブに動作しますが、私のスクリプトでは機能しないのはなぜですか? [コピー]

sedコマンドがインタラクティブに動作しますが、私のスクリプトでは機能しないのはなぜですか? [コピー]

SEDコマンドはDebianのbashを置き換えませんが、コマンドラインで使用できます。

コマンドラインでの作業:

sed -i 's|/dev/disk/by-label/SR6D4|/dev/disk/by-label/SR4D4|g' /etc/my/config.xml

Bashスクリプトでは機能しません。文字列を置き換えません。

from="SR6D4"
to="SR4D4"
path_from="/dev/disk/by-label/${from}"
path_to="/dev/disk/by-label/${to}"
echo "sed -i 's|${path_from}|${path_to}|g' $file"
sed -i 's|${path_from}|${path_to}|g' $file

Bashでsedを使用するときにファイルの文字列が置き換えられないのはなぜですか?

答え1

シェル変数は一重引用符内では拡張されません。 (これは一重引用符の使用に似ています。)

sed -i "s|${path_from}|${path_to}|g" "$file"

もっとうまくいくはずです。 ($fileファイル名にスペースが含まれている場合に備えて二重引用符を追加しました。)

答え2

述べたように、引用に問題があります。ただし、ファイル内の文字列の置き換えについてはいくつかのコメントがあります。下記をご覧ください。

ファイルの文字列を置き換えるのは安全ではないので、悪い考えです。変更するとファイルデータが失われる可能性が低くなります。

変更する前にファイルをバックアップしてみてください。

cp /path/to/file{,.backup}
sed -i 'place your pattern here' /path/to/file

というファイルを受け取りますfile.backup

覚えておくべきこと:ファイルが破損してファイルを削除して置き換えると、ファイルには別のinodeがあり、すべてのハードリンクが失われます。

2番目のセキュリティ方法:

mv /path/to/file{,.backup}; 
cat /path/to/file.backup | sed 'place your pattern here' > /path/to/file

次のポイント。 〜のようにbash よくある質問は思います:

sedコマンドにシェル変数を含めることは決して良い考えではありません。

awkそのため、optionsを使用する必要があります-v。スクリプトは次のとおりです。

from="SR6D4"
to="SR4D4"
path_from="/dev/disk/by-label/${from}"
path_to="/dev/disk/by-label/${to}"
sed -i 's|${path_from}|${path_to}|g' $file
mv $file{,.backup}
cat "${file}.backup" | awk -v awkfrom="$path_from" -v awkto="$path_to" '{gsub(awkfrom,awkto)}' > $file

関連情報