Como grep milhares de arquivos em um diretório para centenas de seqüências de caracteres em um arquivo

11

Estou tentando compor uma instrução grep e isso está me matando. Eu também estou cansado de obter o erro arguments list too long . Eu tenho um arquivo, vamos chamá-lo subset.txt . Ele contém centenas de linhas com strings específicas, como MO43312948 . No meu diretório de objetos eu tenho milhares de arquivos e eu preciso copiar todos os arquivos que contenham as strings listadas em subset.txt em outro diretório.

Eu estava tentando começar com isso apenas para retornar os arquivos correspondentes do diretório de objetos.

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

Eu continuo recebendo 'bash: / bin / grep: Lista de argumentos muito longa' '

    
por Revlis 29.12.2016 / 16:18

3 respostas

23

Você pode passar um diretório como um destino para grep com -R e um arquivo de padrões de entrada com -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.

Então, você está procurando:

grep -Ff subset.txt -r objects/

Você pode obter a lista de arquivos correspondentes com:

grep -Flf subset.txt -r objects/

Então, se a sua lista final não for muito longa, você pode fazer:

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

Se isso retornar um erro argument list too long , use:

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

E se os nomes dos seus arquivos puderem conter espaços ou outros caracteres estranhos, use (assumindo o GNU grep ):

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

Finalmente, se você quiser excluir arquivos binários, use:

grep -IFZlf subset.txt -r objects/ | xargs -0I{} mv {} bar/
    
por 29.12.2016 / 16:28
11

use

grep -F -f subset.txt 

para dizer ao grep para ler o arquivo subset.txt .

você pode usar encontrar para percorrer o arquivo.

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

ou

find . -type f -exec grep -F -f subset.txt {}  +
    
por 29.12.2016 / 16:25
3

Se você quiser acelerar ainda mais o grep, você pode definir o código do idioma no seu shell antes de executá-lo, ou seja, use "LC_ALL = c". Isso será herdado no grep e desativará o processamento Unicode quando não for necessário e, em alguns casos, pode acelerar drasticamente o grep. Um ótimo blog documentando isso pode ser encontrado no link . Esse truque também pode acelerar os scripts do shell bash, não apenas o grep.

    
por 29.12.2016 / 23:09

Tags