多数のプレーンテキストファイルの内容内で検索していますか?

多数のプレーンテキストファイルの内容内で検索していますか?

私の外付けハードドライブには、1,242,276個のプレーンテキストファイルを含むディレクトリがあります。完全に整理されておらず、ファイル名も意味のない数字です。その理由は、しばらく前に誤ってパーティションを消去した後、一部の回復ソフトウェアによってパーティションが回復したためです。

私は現在そのディレクトリにあり、「多面体」という単語のすべてのファイルの内容を検索しようとしています。試しましたがgrep失敗しました。

$ grep polyhedron ./* 
bash: /bin/grep: Argument list too long

このディレクトリにファイルが多すぎるからですか?この他にも検索したいキーワードがたくさんあります。今何ができるか知りたいです。

答え1

find . -type f -print0 | xargs -0 grep polyhedron

用語が一致するファイルを同じ名前のフォルダにコピーするなどの操作を実行したい場合があります。

find . -type f -print0 | xargs -0 grep -l polyhedron | while read i; do cp "$i" ../polyhedron; done

一致する用語の間に重複する部分がないことがわかっている場合(つまり、単一のファイルに「多面体」と構成する他の用語がない)、コピーするmv代わりに移動できますcp

答え2

これはファイルが多すぎるためではなく、命令のパラメータリストが長すぎるためgrepです。これはexecve(2)、システムコールが呼び出しを介して渡される引数リストと環境変数リストの組み合わせサイズに適用される制限です。

ulimit -sLinuxでは、2.6.23以降、以下を使用して増やしたり解放したりできる管理制限です(プロセススタックサイズの制限も設定します)。だから

ulimit -s unlimited

あなたに適しているかもしれません。

それ以外の場合、回避策(ほとんどの他の回答で言及されています)は、その制限に合うように引数リストを分割するか、ファイルリストをexecve

ls | xargs grep polyhedron

(わかりました。ファイル名には数字のみが含まれているためです。)

(xargsはリストを分割し、制限に達しないように必要grepなだけ多くのコマンドを実行します。)execve

find . -exec grep polyhedron {} +

同じですが、今回は分割されfindました。

grep -r polyhedron .

(grepがサポートしている場合-r)今回は3つのパラメータのうち数文字だけが渡され、内部的にファイルリストをgrep作成grepし、execveシステムコールに渡しません。

一部の殻には組み込みそれをサポートしてください。

組み込みシェルの場合、grepこの問題は発生しません。組み込みシェルがそうではないからです。処刑されたシステムコールを介してexecve

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

command -x grep polyhedron *

そしてksh93分割されます。

zsh次のコマンドがありますzargs

zargs * -- grep polyhedron

複数の単語を検索するには:

grep -e word1 -e word2 ...

または

grep 'word1
word2
...' ...

または、単語リストを1行に1つずつファイルに入れて使用します。

grep -f that-file ...

答え3

このディレクトリにファイルが多すぎるからですか?

はい。ワイルドカード拡張を使用します。これはコマンドラインに展開されたすべてのファイル名です。長さの制限のため、この操作は失敗しました。この制限を確認するには、以下を試してください。

getconf ARG_MAX

この他にも検索したいキーワードがたくさんあります。今何ができるか知りたいです。

grep再帰モードを試してみましたか?

grep -r polyhedron .

他の答えが示すように、他の方法があります。この記事問題に関するいくつかの背景知識と、この長さの制限を回避する方法の追加例も提供されています。

アイデアを提供するために、ここにいくつかの例をコピーしました。

使用find:

find /nas/data/accounting/ -type f -exec ls -l {} \;

使用xargs:

echo /nas/data/accounting/* | xargs ls -l

whileループを使用してください:

find /nas/data/accounting/ -type f |
  while read file
  do
    mv /nas/data/accounting/$file /local/disk/
  done

答え4

あなたは試すことができます:

find . -print0|xargs -0 grep 'term1\|term2'

xargsgrepデフォルトの最大パラメータを使用して複数のコマンドが生成されます。それでも「引数リストが長すぎます」というエラーが発生してgrepいる--max-args場合xargs。複数の用語で検索できます。多くの文書があるので、方法を見たいと思うかもしれません。
-print0-0
\|
最適化grep

関連情報