web-dev-qa-db-ja.com

予行演習でのsedコマンド

Sedを使用してドライランを実行できるかどうか、またどのように実行できるかを確認できません。

だから私はこのコマンドを持っています:

find ./ -type f | xargs sed -i 's/string1/string2/g'

しかし、実際にすべてのファイルを置き換える前に、何が置き換えられるかを確認したいと思います。ディレクトリ構造全体をコピーして確認することはできません。

フィードバックをありがとう(否定的または肯定的:))

47
dmeu

-iを削除してlessにパイプし、結果をページ分割します。または、-iを削除して> dryrun.outを追加することで、全体を1つの大きなファイルにリダイレクトできます。

このスクリプトは、名前にスペースが含まれているファイルや、改行などの悪意のある文字が含まれていると、無残に失敗することに注意してください。それを行うより良い方法は次のとおりです。

while IFS= read -r -d $'\0' file; do
  sed -i 's/string1/string2/g' "$file"
done < <(find ./ -type f -print0)
32
SiegeX

私はpオプションを使用したいと思います:

find ./ -type f | xargs sed 's/string1/string2/gp'

--quietパラメーターと組み合わせて、冗長な出力を減らすことができます。

find ./ -type f | xargs sed --quiet 's/string1/string2/gp'

man sedから:

p:

現在のパターンスペースを印刷します。

- 静か:

パターンスペースの自動印刷を抑制

15
Murmel

私はこれが非常に古いスレッドであることを知っており、OPはこの答えを本当に必要としませんが、私は予行演習モードを探してここに来たので、将来ここに来る人のために以下のアドバイスを追加することを考えました。私がやりたかったのは、本当に何かが変わっていない限り、バックアップファイルを踏みつけないようにすることでした。 -iオプションとバックアップサフィックスを使用して盲目的にsedを実行すると、何も置換されていない場合でも、既存のバックアップファイルが上書きされます。

私がやった方法は、sedの出力をdiffにパイプし、何か変更されていないか確認してから、次のようなインプレース更新オプションでsedを再実行することです。

if ! sed -e 's/string1/string2/g' $fpath | diff -q $fpath - > /dev/null 2>&1; then
    sed -i.bak -e 's/string1/string2/g' $fpath
fi

OPの質問によると、何が変化するかを確認することが要件である場合は、その場でsedを実行する代わりに、いくつかの情報メッセージを使用してdiffを再度実行できます。

if ! sed -e 's/string1/string2/g' $fpath | diff -q $fpath - > /dev/null 2>&1; then
    echo "File $fpath will change with the below diff:"
    sed -e 's/string1/string2/g' $fpath | diff $fpath -
fi

変数に出力をキャプチャして、2回実行することを回避することもできます。

diff=$(sed -e 's/string1/string2/g' $fpath | diff $fpath -)
if [[ $? -ne 0 ]]; then
    echo "File $fpath will change with the below diff:"
    echo "$diff"
fi
6
haridsv