web-dev-qa-db-ja.com

検索結果でxargsを使用する場合、ファイル名のスペースをどのように処理できますか?

私の一般的な方法の1つは、特定のタイプのすべてのファイルに対してgrepsを実行することです。たとえば、「rumpus」という単語が含まれているすべてのHTMLファイルを見つけます。それをするために、私は使用します

find /path/to -name "*.html" | xargs grep -l "rumpus"

場合によっては、findmy new file.htmlなどの名前にスペースが含まれるファイルを返します。 xargsがこれをgrepに渡すと、次のエラーが発生します。

grep: /path/to/bad/file/my: No such file or directory
grep: new: No such file or directory
grep: file.html: No such file or directory

私はここで何が起こっているかを見ることができます:パイプまたはxargsはスペースをファイル間の区切り文字として扱います。けれども、私の生活の中で、私はこのふるまいを防ぐ方法を理解することができません。 find + xargsで実行できますか?または、まったく異なるコマンドを使用する必要がありますか?

29
abeger

使用する

find ... -print0 | xargs -0 ...

例えば.

find /path/to -name "*.html"  -print0 | xargs -0  grep -l "rumpus"

findのmanページから

-print0
          True; print the full file name on the standard  output,  followed
          by  a  null  character  (instead  of  the  newline character that
          ‘-print’ uses).  This allows file names that contain newlines  or
          other  types  of  white space to be correctly interpreted by pro-
          grams that process the find output.  This option  corresponds  to
          the ‘-0’ option of xargs.
29
user9517

findはコマンド自体を実行できるため、xargsを使用する必要はありません。これを行う場合、シェルが名前の文字を解釈することを心配する必要はありません。

find /path/to -name "*.html" -exec grep -l "rumpus" '{}' +

findのmanページから

-execコマンド{} +
-execアクションのこのバリアントは、選択されたファイルに対して指定されたコマンドを実行しますが、コマンドラインは、選択された各ファイル名を末尾に追加することによって構築されます。コマンドの呼び出しの総数は、一致したファイルの数よりもはるかに少なくなります。コマンドラインは、xargsがコマンドラインをビルドするのとほぼ同じ方法でビルドされます。コマンド内では、 `{} 'のインスタンスを1つだけ使用できます。コマンドは、開始ディレクトリで実行されます。

16
sciurus

システムのfindおよびxargバージョンが-print0および-0スイッチをサポートしていない場合(たとえば、AIXのfindおよびxargs)、これを使用できます。

find /your/path -name "*.html" | sed 's/ /\\ /g' | xargs grep -l "rumpus"

ここで、sedはxargsのスペースをエスケープします。

8
Jan Ptáčník