次を使用して、特定の文字列をディレクトリで再帰的に検索し、別の文字列に置き換えます。
grep -rl oldstr path | xargs sed -i 's/oldstr/newstr/g'
これで問題ありません。唯一の問題は、文字列が存在しない場合、引数を取得しないため、sed
が失敗することです。私はこれをANTで自動的に実行しており、sed
が失敗するためビルドが失敗するため、これは私にとって問題です。
文字列が見つからない場合にフェイルプルーフにする方法はありますか?
私が使用できる1行のシンプルなソリューションに興味があります(grep
またはsed
である必要はありませんが、これらのような一般的なUNIXコマンドを使用します)。
最初にfind
でsed
を見つけるのではなく、oldstr
と-exec
を直接grep
に使用できます。多分少し効率が悪いかもしれませんが、それは重要ではないかもしれません。このように、sed
置換はfind
でリストされたすべてのファイルに対して実行されますが、oldstr
が存在しない場合、明らかに動作しません。
find /path -type f -exec sed -i 's/oldstr/newstr/g' {} \;
あなたのソリューションは大丈夫です。この方法でのみ試してください:
files=$(grep -rl oldstr path) && echo $files | xargs sed....
そのため、grepが0
を返すときにのみxargs
を実行します。一部のファイルで文字列が見つかったとき。
Vladのアイデアを取り入れて、少し変更しました。の代わりに
grep -rl oldstr path | xargs sed -i 's/oldstr/newstr/g' /dev/null
どちらが得られますか
sed: couldn't edit /dev/null: not a regular file
リモートサーバーへの3つの異なる接続で実行しています
touch deleteme
grep -rl oldstr path | xargs sed -i 's/oldstr/newstr/g' ./deleteme
rm deleteme
これはエレガントではなく、サーバーへの接続がさらに2つ必要です(すべてを1行で行う方法があるかもしれません)。
標準xargs
には適切な方法がありません。他の人が示唆したようにfind -exec
を使用するか、引数がない場合は何もしないスクリプトでsed
をラップする方が良いでしょう。 GNU xargs
には--no-run-if-empty
オプションがあり、BSD/OS X xargs
には-L
オプションがあり、似たような動作をするはずです。
-exec
を使用しなくても、何も見つからない場合に少なくとも1つの引数として/dev/null
を指定することができます。
grep -rl oldstr path | xargs sed -i 's/oldstr/newstr/g' /dev/null
私のユースケースでは、foo:/Drive_Letter
をfoo:/bar/baz/xyz
に置き換えたいと思いました。私の場合、次のコードでそれを行うことができました。大量のファイルがあった同じディレクトリの場所にいました。
find . -name "*.library" -print0 | xargs -0 sed -i '' -e 's/foo:\/Drive_Letter:/foo:\/bar\/baz\/xyz/g'
お役に立てば幸いです。