sed フル置換を実行して変更されたファイルのみをバックアップするにはどうすればよいですか?

sed フル置換を実行して変更されたファイルのみをバックアップするにはどうすればよいですか?

現在の作業ディレクトリ内のすべてのファイルで使用されている用語を置き換えるには、次のコマンドを実行します。

$ find . -type f -print0 | xargs -0 sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g'

これは単語置換を実行しますが、.bup文字列を含むファイルがまったく含まれていないファイルも生成しますMs. Johnson

不要なバックアップを作成せずに交換を実行するにはどうすればよいですか?

答え1

-execFindには任意のコマンドを実行する演算子があります。より良い点-execテスト、複数のコマンドを一緒に接続でき、-exec前のコマンドが失敗した場合、以降のコマンドは実行されません。この文字列は{}現在のファイル名に変更され、;コマンドの終わりを表示します。シェル干渉を防ぐために、両方を引用する必要があります。

だから:

find . -type f \
    -exec grep -q 'Ms. Johnson' '{}' \; \
    -exec sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g' '{}' \;

答え2

ファイルの内容を確認して、sedファイルの操作時に交換が発生するかどうかを確認できます。

find . \
    -type f \
    -exec grep -q 'Ms. Johnson' {} \; \
    -print0 |
xargs -0 sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g'

本当に賢くなりたいなら、find以下を完全に使う必要はありません。

grep -Z -l -r 'Ms. Johnson' |
    xargs -0 sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g'

答え3

マニュアルページを見ましたが、これを行うための直接的な方法が見つかりませんでしたsed。あなたが質問する前にそうしたと確信しています。 grepを使ってこの問題を解決するいくつかの方法を見ましたが、最も簡単な方法は次のとおりです。

grep -rlZ "Ms. Johnson" . | xargs -0 sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g'

-rnull で終わる名前
-lだけを使用して、ファイル名を繰り返し印刷します。
-Z

答え4

まず、クエリに一致するファイルのリストを作成する必要があるようです。

search="test"
for match in $(find -type f -exec grep -l $search "{}" \;)
do sed -i'.bup' -e "/$search/ s/$search/Mrs. Melbin/g" "$match"
done

関連情報