あるコマンドから別のコマンドに結果を送信するときにbashで空白を処理する

あるコマンドから別のコマンドに結果を送信するときにbashで空白を処理する

複数のディレクトリ/ファイルを繰り返し繰り返す必要があり、bashファイルに特定の文字列がある場合は別の文字列に置き換える必要があります。私のスクリプトでは、次の行を使用してこの問題を解決しました。

grep -rl "stringToReplace" * | xargs sed -ie 's/stringToReplace/newString/'

一部のファイルの名前に空白があることがわかるまではそうです。したがって、というファイルがある場合は、"dir1/dir2/I Am A File.txt"sedに4つのファイル(、および)xargsを供給してみてください。"dir1/dir2/I""Am""A""File.txt"

この問題を解決するために私が考えることができるすべての方法を試しましたが、それでも機能しません。誰にもアイデアがありますか?

ベストアンサー1

grep | xargs複雑なファイル名を安全に処理できないため、この種の作業に最適なツールではありません。ただし、ファイル名に改行文字が含まれていない場合は、いくつかのオプションがあります。

grep -rl "stringToReplace" * | xargs -I {} sed -ie 's/stringToReplace/newString/' {}

これは以下に適用されます。すべて(XSI)POSIX規格xargs-I {}1行の処理を強制し、引数にある{}場合はファイルの名前を変更します。

GNU grepでは、次のことができます。

grep -rl "stringToReplace" * | xargs -d '\n' sed -ie 's/stringToReplace/newString/'

これは、区切り文字としてスペースの代わりに改行文字を明示的に使用するが移植できない拡張です。

改行文字を含む鈍いファイル名を含む、すべての可能なファイル名を尊重する方が安全です。このPOSIXfindコマンド:

find . -type f -exec grep -q "stringToReplace" {} \; -exec sed -ie 's/stringToReplace/newString/' {} +

多くのgrepsを生成します。 1つ目は-exec現在のディレクトリで見つかった通常のファイルごとに1回実行され、2つ目は最初のものが成功を返すファイルグループでのみ実行されます(つまり、grepファイル内のパターンが見つかった場所)。 。追加のプロセスは、現在実行中の作業に大きな問題ではないかもしれませんが、特定のファイルシステムに小さなファイルがたくさんある場合は支配的かもしれません。

より安全ですが、移植性の低い-execdirGNUとBSDのメジャーバージョンはfind基本的に同じことを行いますが、特定の名前変更攻撃から保護します。

おすすめ記事