Qual é a melhor maneira de pesquisar com regex ou encontrar com grep?

4

Destes dois modos de pesquisar um arquivo recursivamente em todos os subdiretórios, o que é mais rápido / melhor?

find . -regex ".*/.*abc.*"

ou

find . | grep ".*abc.*"
    
por user13107 12.09.2012 / 21:33

3 respostas

6

O nome do arquivo UNIX geralmente consiste em octetos (bytes de 8 bits), exceto 0x00 (NULL) e 0x2F (/). Todos os outros octetos são válidos. Isso inclui coisas legais como 0x0A (nova linha).

Seu find exemplo tratará nomes de arquivos com caracteres estranhos, como newline, corretamente.

Seu find | grep exemplo dará resultados estranhos e incorretos quando confrontado com uma coisa dessas (verá um arquivo chamado "linha 1 \ nlinha 2" como dois arquivos).

Você pode usar find -print0 | grep -z (se você estiver usando versões GNU, por exemplo, no Linux); Isso preservará a correção. Vai usar um pouco mais de memória. Note que você pode dizer ao find para usar expressões regulares estendidas (por exemplo) usando a opção -regextype .

Se você quiser fazer uma correspondência muito complicada, pode gostar do script find2perl , que converterá uma linha de comando find em um programa perl curto que você pode editar para adicionar na complexidade.

    
por 12.09.2012 / 21:50
6

find . -regex ".*/.*abc.*" é mais rápido porque find . | grep ".*abc.*" precisa ter find para gerar todos os dados e passá-los para grep . A diferença é provável que seja pequena embora. find . -regex ".*/.*abc.*" também é mais confiável, porque funciona mesmo no caso raro em que você tem nomes de arquivos com espaços.

Observe que ambos os comandos procuram arquivos cujo caminho completo contenha abc . Isso inclui não apenas arquivos cujo nome contém abc , mas também arquivos contidos em um diretório cujo nome contenha abc , recursivamente. Para localizar apenas arquivos cujo nome contenha abc , use

find -name '*abc*'

Em ksh, bash ou zsh, você pode executar echo **/*abc* : **/ procura dentro de todos os subdiretórios recursivamente. Em ksh, você precisará executar set -o globstar primeiro (coloque isso em ~/.kshrc ). No bash, você precisará executar shopt -s globstar primeiro (coloque isso no seu ~/.bashrc ).

    
por 13.09.2012 / 02:09
4

Se você usar a correspondência de padrões com find , poderá adicionar outros predicados ou comportamentos:

# look only for matching directories
find . -regex ".*/.*abc.*" -type d

# run a command on each match
find . -regex ".*/.*abc.*" -exec echo 'I found a file named {}' ';'

find pode ser mais rápido apenas para pesquisar, porque você não precisa gerar um processo grep ou executar qualquer tubulação; mas duvido que você seja capaz de perceber.

    
por 12.09.2012 / 21:41

Tags