ディレクトリ内の何千ものファイルのうち、1つのファイルから何百もの文字列を見つける方法

ディレクトリ内の何千ものファイルのうち、1つのファイルから何百もの文字列を見つける方法

声明書を書こうとするのにgrep本当に死にます。私もarguments list too longエラーが発生して疲れました。ファイルがありますが、名前をとして指定しますsubset.txt。これには、特定の文字列(たとえば)を含む数百行が含まれています。私のオブジェクトディレクトリには何千ものファイルがあり、リストされた文字列を含むすべてのファイルを別のディレクトリにMO43312948コピーする必要があります。subset.txt

ここでは、オブジェクトディレクトリから一致するファイルのみを返すことから始めたいと思います。

grep -F "$(subset.txt)" /objects/*

「bash: /bin/grep: 引数のリストが長すぎます」というメッセージが表示されます。

答え1

grep宛先にディレクトリを渡し、-R入力スキーマファイルを渡すことができます-f

  -f FILE, --file=FILE
          Obtain patterns from FILE, one per line.  If this option is used
          multiple  times  or  is  combined with the -e (--regexp) option,
          search for all patterns given.  The  empty  file  contains  zero
          patterns, and therefore matches nothing.

   -R, --dereference-recursive
          Read all files under each directory,  recursively.   Follow  all
          symbolic links, unlike -r.

だからあなたは以下を探しています:

grep -Ff subset.txt -r objects/

以下を使用して、一致するファイルのリストを取得できます。

grep -Flf subset.txt -r objects/

したがって、最終リストが長すぎない場合は、次のことができます。

 mv $(grep -Flf subset.txt -r objects/) new_dir/

argument list too longエラーが返された場合は、以下を使用してください。

grep -Flf subset.txt -r objects/ | xargs -I{} mv {} bar/

ファイル名にスペースやその他の奇妙な文字を含めることができる場合は、以下を使用してください(GNUと仮定grep)。

grep -FZlf subset.txt -r objects/ | xargs -0I{} mv {} bar/

最後にバイナリを除外するには、次のようにします。

grep -IFZlf subset.txt -r objects/ | xargs -0I{} mv {} bar/

答え2

使用

grep -F -f subset.txt 

grepにsubset.txtファイルを読み込むように指示します。

findを使用してファイルを繰り返すことができます。

find . -type f -exec grep -F -f subset.txt {} \;

または

find . -type f -exec grep -F -f subset.txt {}  +

答え3

grepをさらに高速化するには、実行前に "LC_ALL = c"を使用してシェルでロケールを設定できます。これはgrepに継承され、必要でない場合はUnicode処理を無効にし、場合によってはgrep速度を大幅に向上させることができます。これを文書化したすばらしいブログは、以下にあります。http://www.inmotionhosting.com/support/website/ssh/speed-up-grep-searches-with-lc-all。このトリックはgrepだけでなく、bashシェルスクリプトのスピードを高めることができます。

関連情報