
Talvez seja um pouco estranho - e talvez existam outras ferramentas para fazer isso, mas, bem...
Estou usando o seguinte comando bash clássico para localizar todos os arquivos que contêm alguma string:
find . -type f | xargs grep "something"
Tenho um grande número de arquivos, em múltiplas profundidades. a primeira ocorrência de "alguma coisa" é suficiente para mim, mas find 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 find possa parar de procurar por mais arquivos. É possível uma coisa dessas?
Responder1
Simplesmente mantenha-o dentro do reino de find:
find . -type f -exec grep "something" {} \; -quit
É assim que funciona:
A -exec
vontade funcionará quando -type f
for verdade. E como grep
retorna 0
(sucesso/verdadeiro) quando -exec grep "something"
há uma correspondência, o -quit
será acionado.
Responder2
find -type f | xargs grep e | head -1
faz exatamente isso: quando head
termina, o elemento intermediário do pipe é notificado com um sinal de 'tubo quebrado', termina por sua vez e notifica o find
. Você deverá ver um aviso como
xargs: grep: terminated by signal 13
o que confirma isso.
Responder3
Para fazer isso sem trocar de 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