web-dev-qa-db-ja.com

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

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

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

これにより、Wordの置換が実行されましたが、.bup文字列を持たないファイルのMs. Johnsonファイルも作成されました。

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

13

ファイルの内容をチェックして、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'
6
amphetamachine

Findには、任意のコマンドを実行する-exec演算子があります。さらに良いことに、-exectestであるため、複数の-execを連鎖させることができ、前のコマンドが失敗した場合、後のコマンドは実行されません。文字列{}は現在のファイル名に置き換えられ、;はコマンドの終了を示します。シェルの干渉を避けるために、両方を引用する必要があります。

そう:

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

私はmanページを確認しましたが、sedから直接実行する方法はありませんでした。 grepを使用してこれを回避する方法はいくつかありますが、最も簡単な方法は次のとおりです。

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

-r再帰
-lファイル名のみを印刷
-Z名前をnullで終了

4
Kevin