3

ファイル名 (およびそれらへのフル パス) を含むファイルがあり、それらすべての中から単語を検索したいと考えています。説明する擬似コード:

grep keyword <all files specified in files.txt>

また

cat files.txt > grep keyword
cat files txt | grep keyword

問題は、実際のファイルの内容ではなく、ファイル名を検索するために grep しか取得できないことです。

4

5 に答える 5

7
cat files.txt | xargs grep keyword

また

grep keyword `cat files.txt`

または(前と同等だが読み違えにくい)

grep keyword $(cat files.txt)

トリックを行う必要があります。

落とし穴:

  • files.txt にスペースを含むファイル名が含まれている場合、「This is a filename.txt」は「This」、「is」、「a」、および「filename.txt」の 4 つのファイルとして解釈されるため、どちらのソリューションも誤動作します。ファイル名にスペースを入れてはいけないという正当な理由があります。

    • これを回避する方法はありますが、どれも簡単ではありません。(find ... -print0 / xargs -0 はそのうちの 1 つです。)
  • 2 番目の (cat) バージョンでは、コマンド ラインが非常に長くなる可能性があります (環境の制限を超えると失敗する可能性があります)。最初の (xargs) バージョンは長い入力を自動的に処理します。xargs には、詳細を制御するためのオプションがいくつか用意されています。

于 2009-03-27T10:11:21.417 に答える
2
tr '\n' '\0' <files.txt | LANG=C xargs -r0 grep -F keyword
  • tr は名前を NUL 文字で区切って、スペースが意味をなさないようにします (xargs の対応する -0 オプションに注意してください)。
  • xargs -r は、「多数の」ファイルに対して単一の grep プロセスを開始しますが、ファイルがない場合は grep プロセスを開始しません。
  • LANG=C は、遅いロケールのものではなく、マッチングに迅速なルーチンを使用することを意味します
  • grep -F は、遅い正規表現マッチングではなく、迅速な文字列マッチングを使用することを意味します
于 2009-03-27T14:59:53.643 に答える
2

DevSolar からの両方の回答 (Linux Ubuntu でテスト済み) が機能しますが、コマンド ラインの長さの制限に達するのを回避できるため、多くのファイルがある場合は xargs バージョンが推奨されます。

それで:

cat files.txt | xargs grep keyword

行く方法です

于 2009-03-27T10:23:16.333 に答える
-2

最後に bash シェル スクリプトを作成してから長い時間が経ちましたが、最初の grep (すべてのファイル名を検索したもの) の結果を配列に格納し、それを反復処理して、さらに grep コマンドを発行することができます。

適切な出発点は、bash スクリプト ガイドです。

于 2009-03-27T10:10:57.207 に答える