何千ものファイルの Grep

何千ものファイルの Grep

私のディレクトリには26,000個のファイルがあり、すべてのファイルをgrepする必要があります。問題はできるだけ早くインポートする必要があるため、findコマンドからファイル名を取得し、一致をファイルに書き込むgrepスクリプトを作成するのは理想的ではありません。 「パラメータリストが多すぎる」問題が発生する前に、これらのファイルをすべて収集するのに約2分かかりました。どうすればいいのアイデアはありますか?編集:新しいファイルを生成し続けるスクリプトがあるため、すべてのファイルを別のディレクトリに配置することは不可能です。

ベストアンサー1

そしてfind

cd /the/dir
find . -type f -exec grep pattern {} +

-type f検索専用です。定期的なファイル(通常のファイルを指してもシンボリックリンクではありません)。ディレクトリを除くすべての種類のファイルを検索する場合(ただし、fifosや/dev/zeroなどの一部のファイルタイプは通常読みたくありません)、-type fGNU固有のファイルに置き換えます! -xtype d-xtype d次のファイルと一致)。タイプ目次シンボリックリンク解決後))。

GNUの使用grep:

grep -r pattern /the/dir

(ただし、最新バージョンのGNU grepがない場合は、ディレクトリに入るときにシンボリックリンクに従う必要があります。)オプションを追加しないと、珍しいファイルは検索されません-D read。ただし、最新バージョンのGNUはgrepまだシンボリックリンク内で検索されません。

非常に古いバージョンのGNUはfind標準構文をサポートしていませんが、非{} +標準構文を使用できます。

cd /the/dir &&
  find . -type f -print0 | xargs -r0 grep pattern

パフォーマンスによっては、I/O が制限される場合があります。つまり、検索を実行するのにかかる時間は、リポジトリ内のすべてのデータを読み取るのにかかる時間です。

データが冗長ディスクアレイにある場合は、複数のファイルを同時に読み取るとパフォーマンスが向上する可能性があります(そうしないとパフォーマンスが低下する可能性があります)。並行性は、パフォーマンスがI / Oバインドされていない(たとえば、すべてのデータがキャッシュにあるため)、CPUが複数ある場合にもgreps役立ちます。 GNUxargsのオプションを使用して-Pこれを行うことができます。

たとえば、データが3つのドライブを持つRAID1アレイにある場合、またはデータがキャッシュにあり、3つのCPUがアイドル状態の場合:

cd /the/dir &&
  find . -type f -print0 | xargs -n1000 -r0P3 grep pattern

(ここでは、1000ファイルごとに-n1000新しいファイルを作成し、grep一度に最大3つのファイルを並列に実行するために使用されました。)

ただし、出力grepがリダイレクトされると、3つのプロセスで重大にインターリーブされた出力が生成されますgrep。この場合、次のように実行できます。

find . -type f -print0 | stdbuf -oL xargs -n1000 -r0P3 grep pattern

(最近のGNUまたはFreeBSDシステムで)または--line-bufferedGNUオプションを使用してくださいgrep

pattern固定文字列の場合、このオプションを追加すると-F問題が改善する可能性があります。

マルチバイト文字データでない場合、またはパターンマッチングのためにデータがマルチバイト文字であるかどうかが重要でない場合は、次のようにします。

cd /the/dir &&
  LC_ALL=C grep -r pattern .

パフォーマンスを大幅に向上させることができます。

この種の検索を頻繁に実行すると、多くの検索エンジンのいずれかを使用してデータをインデックス化できます。

おすすめ記事