現在の作業ディレクトリ内のすべてのファイルで使用されている用語を置き換えるには、次のコマンドを実行します。
$ find . -type f -print0 | xargs -0 sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g'
これは単語置換を実行しますが、.bup
文字列を含むファイルがまったく含まれていないファイルも生成しますMs. Johnson
。
不要なバックアップを作成せずに交換を実行するにはどうすればよいですか?
答え1
-exec
Findには任意のコマンドを実行する演算子があります。より良い点-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'
-r
null で終わる名前
-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