Como encontrar a primeira correspondência em vários arquivos

4

Existe uma maneira de o comando find pesquisar a primeira correspondência ou ocorrência de uma string ou padrão dentro de cada de vários arquivos? Eu tenho usado a sintaxe usual:

 find dir -iname '*.ext' -exec command 'pattern' {} \;

(Eu também estou pesquisando pdfs com -exec pdfgrep , mas suponho que seria um caso especial do problema geral e pode ser tratado depois ou separadamente.)

Lembre-se de que isso não é o mesmo que o problema comumente produzido de produzir o primeiro resultado de uma pesquisa usando a localização com -quit ou head -n 1 .

    
por gaberlunzie 31.07.2013 / 23:32

3 respostas

7

Basta usar a opção -m do GNU grep , que interrompe a leitura do arquivo após (no exemplo) uma correspondência.

find dir -iname '*.ext' -exec grep -m 1  'pattern' {} \;
    
por 31.07.2013 / 23:40
2

Você pode fazer isso com um script awk:

find dir -iname '*.ext' -exec awk '/pattern/{print;exit}' {} \;
    
por 31.07.2013 / 23:41
2

Se o comando de pesquisa não tiver como parar após a primeira correspondência, você poderá filtrar seus resultados e manter apenas a primeira linha de saída: command 'pattern' /path/to/file | head -n 1 . O comando receberá um sinal SIGPIPE quando head sair, então ele pode continuar procurando por mais algumas correspondências devido ao buffer, mas irá parar antes do final do arquivo se houver muitas correspondências.

Como você precisa executar um comando shell (para configurar o canal), é necessário invocar sh de find . Lembre-se das citações: você precisa de uma camada de citações para o shell externo e outra para o shell iniciado por find . Você pode colocar aspas simples em torno do comando shell interno e trabalhar entre aspas simples com '\'' hack (final, literal de aspas simples, \' para uma aspa simples literal e iniciar um novo literal de aspas simples na mesma respiração). de maneira que você não precise de nenhuma cotação diferente no padrão (a menos que o padrão contenha um ' que você representou como '\'' , nesse caso você precisará fazer esse '\'\\'\'' ).

find dir -iname '*.ext' -exec sh -c 'command '\''pattern'\'' "$0" | head -n 1' {} \;

Em vez de se preocupar em citar o padrão, você pode colocá-lo fora e passá-lo como parâmetro.

find dir -iname '*.ext' -exec sh -c 'command "$0" "$1" | head -n 1' 'pattern' {} \;

Será um pouco mais rápido invocar apenas um shell e fazer um loop pelos arquivos.

find dir -iname '*.ext' -exec sh -c '
    for f; do command "$0" "$f" | head -n 1; done
' 'pattern' {} +
    
por 01.08.2013 / 01:08