Grep em milhares de arquivos

12

Eu tenho o diretório com cca 26 000 arquivos e preciso grep em todos esses arquivos. O problema é que eu preciso disso o mais rápido possível, então não é ideal fazer o script em que o grep pega o nome de um arquivo do comando find e escreve as correspondências no arquivo. Antes de "lista de argumentos muito longa", demorou cerca de 2 minutos para o grep em todos os arquivos. Alguma ideia de como fazer? edit: existe um script que está criando novos arquivos o tempo todo, portanto não é possível colocar todos os arquivos em dirs diferentes.

    
por user2778979 07.08.2013 / 10:35

3 respostas

20

com find :

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

( -type f é procurar apenas em arquivos regulares (excluindo links simbólicos mesmo se eles apontarem para arquivos regulares) Se você quiser procurar em qualquer tipo de arquivo, exceto diretórios (mas cuidado) são alguns tipos de arquivos como fifos ou / dev / zero que você geralmente não quer ler), substitua -type f pelo ! -xtype d específico do GNU ( -xtype d corresponde a arquivos do tipo diretório após a resolução do link simbólico)).

Com o GNU grep :

grep -r pattern /the/dir

(mas cuidado, a menos que você tenha uma versão recente do GNU grep, que seguirá links simbólicos ao descer para diretórios). Arquivos não regulares não serão pesquisados, a menos que você adicione uma opção -D read . Versões recentes do GNU grep ainda não irão procurar dentro de links simbólicos.

Versões muito antigas do GNU find não suportam a sintaxe {} + padrão, mas lá você pode usar o não padrão:

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

As apresentações provavelmente são vinculadas a E / S. Essa é a hora de fazer a pesquisa, seria o tempo necessário para ler todos os dados do armazenamento.

Se os dados estiverem em uma matriz de disco redundante, a leitura de vários arquivos por vez poderá melhorar o desempenho (e poderá degradá-los de outra forma). Se as performances não forem vinculadas a E / S (porque, por exemplo, todos os dados estão no cache) e você tiver várias CPUs, o greps simultâneo também poderá ser útil. Você pode fazer isso com a opção xargs do GNU -P .

Por exemplo, se os dados estiverem em uma matriz RAID1 com 3 unidades, ou se os dados estiverem no cache e você tiver 3 CPUs cujo tempo de sobra:

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

(aqui usando -n1000 para gerar um novo grep a cada 1000 arquivos, até 3 executando em paralelo por vez).

No entanto, observe que, se a saída de grep for redirecionada, você terminará com uma saída mal intercalada dos processos de 3 grep . Nesse caso, você pode querer executá-la como:

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

(em um sistema GNU ou FreeBSD recente)

Se pattern for uma string fixa, adicionar a opção -F poderia melhorar as coisas.

Se não forem dados de caracteres de bytes múltiplos, ou se para a correspondência desse padrão, não importa se os dados são caracteres de múltiplos bytes ou não, então:

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

poderia melhorar significativamente o desempenho.

Se você acabar fazendo essas pesquisas com frequência, talvez queira indexar seus dados usando um dos muitos mecanismos de pesquisa existentes.

    
por 07.08.2013 / 10:42
4

26000 arquivos em um único diretório são muito para a maioria dos sistemas de arquivos. É provável que uma parte significativa do tempo seja tomada lendo este grande diretório. Considere dividi-lo em diretórios menores com apenas algumas centenas de arquivos cada.

Chamar find não pode explicar um desempenho ruim, a menos que você faça algo errado. É uma maneira rápida de percorrer um diretório e garantir que você não corra o risco de tentar executar uma linha de comando que seja longa demais. Certifique-se de usar -exec grep PATTERN {} + , que contém quantos arquivos puder por chamada de comando, e não -exec grep PATTERN {} \; , que executa grep uma vez por arquivo: a execução do comando uma vez por arquivo provavelmente será significativamente mais lenta. / p>     

por 08.08.2013 / 01:49
-2

Todos os arquivos no diretório

grep 'search string' *

com recursivamente

grep -R 'search string' *
    
por 07.08.2013 / 10:41