bash encontrar xargs grep apenas ocorrência única

16

Talvez seja um pouco estranho - e talvez haja outras ferramentas para fazer isso, mas ...

Estou usando o seguinte comando bash clássico para encontrar todos os arquivos que contêm alguma seqüência de caracteres:

find . -type f | xargs grep "something"

Eu tenho um grande número de arquivos, em várias profundidades. A primeira ocorrência de "alguma coisa" é suficiente para mim, mas a pesquisa continua pesquisando e leva muito tempo para concluir o restante dos arquivos. O que eu gostaria de fazer é algo como um "feedback" do grep back to find, para que o find pare de procurar mais arquivos. É possível uma coisa dessas?

hello_earth
fonte

Respostas:

20

Basta mantê-lo dentro do domínio de localização:

find . -type f -exec grep "something" {} \; -quit

É assim que funciona:

O -execfuncionará quando o -type ffor verdadeiro. E, como grepretorna 0(sucesso / verdadeiro) quando o resultado -exec grep "something"é correspondido, o resultado -quitserá acionado.

Chen Levy
fonte
8
find -type f | xargs grep e | head -1

faz exatamente isso: quando headtermina, o elemento do meio do tubo é notificado com um sinal de 'tubo quebrado', termina por sua vez e notifica o find. Você deve ver um aviso como

xargs: grep: terminated by signal 13

o que confirma isso.

Kilian Foth
fonte
+1 para explicação e a alternativa, embora a outra resposta parece mais elegante para mim, uma vez que é mais auto-suficientes
hello_earth
8

Para fazer isso sem alterar as ferramentas: (Adoro xargs)

#!/bin/bash
find . -type f |
    # xargs -n20 -P20: use 10 parallel processes to grep files in batches of 20
    # grep -m1: show just on match per file
    # grep --line-buffered: multiple matches from independent grep processes
    #      will not be interleaved
    xargs -P10 -n20 grep -m1 --line-buffered "$1" 2> >(
        # Error output (stderr) is redirected to this command.
        # We ignore this particular error, and send any others back to stderr.
        grep -v '^xargs: .*: terminated by signal 13$' >&2
    ) |
    # Little known fact: all `head` does is send signal 13 after n lines.
    head -n 1
Bukzor
fonte
11
O +1 nunca soube que o xargs teria esses recursos de multitarefa - obrigado por outros comentários também! :)
hello_earth