Não tenho certeza:
grep -r -i 'the brown dog' /*
é realmente o que você quis dizer. Isso significaria grep recursivamente em todos os arquivos e diretórios não ocultos /(mas ainda assim procure dentro de arquivos e diretórios ocultos).
Supondo que você quis dizer:
grep -r -i 'the brown dog' /
Algumas coisas a serem observadas:
- Nem todas as
grepimplementações suportam -r. E entre os que o fazem, os comportamentos diferem: alguns seguem links simbólicos para diretórios ao percorrer a árvore de diretórios (o que significa que você pode acabar procurando várias vezes no mesmo arquivo ou mesmo executar em loops infinitos), outros não. Alguns irão procurar dentro de arquivos de dispositivos (e isso levará algum tempo, /dev/zeropor exemplo) ou tubos ou arquivos binários ..., outros não.
- É eficiente quando
grepcomeça a procurar dentro de arquivos assim que os descobre. Mas enquanto ele aparece em um arquivo, não está mais procurando mais arquivos para pesquisar (o que provavelmente é tão bom na maioria dos casos)
Seu:
find / -type f -exec grep -i 'the brown dog' {} \;
(removido o -rque não fazia sentido aqui) é terrivelmente ineficiente porque você está executando um greppor arquivo. ;deve ser usado apenas para comandos que aceitam apenas um argumento. Além disso, aqui, como grepparece apenas em um arquivo, ele não imprimirá o nome do arquivo, portanto você não saberá onde estão as correspondências.
Você não está olhando dentro de arquivos de dispositivos, canais, links simbólicos ..., não está seguindo links simbólicos, mas ainda está potencialmente olhando dentro de coisas como /proc/mem.
find / -type f -exec grep -i 'the brown dog' {} +
seria muito melhor porque o grepmenor número possível de comandos seria executado. Você obteria o nome do arquivo, a menos que a última execução tenha apenas um arquivo. Para isso, é melhor usar:
find / -type f -exec grep -i 'the brown dog' /dev/null {} +
ou com GNU grep:
find / -type f -exec grep -Hi 'the brown dog' {} +
Observe que grepnão será iniciado até findencontrar arquivos suficientes para mastigar, portanto haverá um atraso inicial. E findnão continuará pesquisando por mais arquivos até que o anterior grepretorne. Alocar e passar a grande lista de arquivos tem algum impacto (provavelmente desprezível); portanto, em geral, será menos eficiente do que um grep -rque não segue o link simbólico ou olha para os dispositivos.
Com as ferramentas GNU:
find / -type f -print0 | xargs -r0 grep -Hi 'the brown dog'
Como acima, o menor número greppossível de instâncias será executado, mas findcontinuará procurando por mais arquivos enquanto a primeira grepchamada estiver dentro do primeiro lote. Isso pode ou não ser uma vantagem. Por exemplo, com os dados armazenados em discos rígidos rotacionais finde o grepacesso a dados armazenados em diferentes locais do disco, a velocidade do disco diminuirá a velocidade, fazendo com que a cabeça do disco se mova constantemente. Em uma configuração de RAID (onde finde greppode acessar discos diferentes) ou em SSDs, isso pode fazer uma diferença positiva.
Em uma configuração de RAID, a execução de várias chamadas simultâneas grep também pode melhorar as coisas. Ainda com as ferramentas GNU no armazenamento RAID1 com 3 discos,
find / -type f -print0 | xargs -r0 -P2 grep -Hi 'the brown dog'
pode aumentar significativamente o desempenho. Observe, no entanto, que o segundo grepserá iniciado apenas quando forem encontrados arquivos suficientes para preencher o primeiro grepcomando. Você pode adicionar uma -nopção xargspara que isso aconteça mais cedo (e passar menos arquivos por grepchamada).
Observe também que, se você estiver redirecionando a xargssaída para algo que não seja um dispositivo terminal, os grepss começarão a armazenar buffer em sua saída, o que significa que a saída desses greps provavelmente será intercalada incorretamente. Você precisaria usar stdbuf -oL(quando disponível, como no GNU ou FreeBSD) neles para solucionar isso (você ainda pode ter problemas com linhas muito longas (normalmente> 4KiB)) ou cada um deles escrever sua saída em um arquivo separado e concatená-los tudo no final.
Aqui, a string que você está procurando é fixa (não uma regexp), portanto, o uso da -Fopção pode fazer a diferença (improvável, pois as grepimplementações já sabem como otimizar isso).
Outra coisa que pode fazer uma grande diferença é fixar o código do idioma em C se você estiver em um código de idioma de vários bytes:
find / -type f -print0 | LC_ALL=C xargs -r0 -P2 grep -Hi 'the brown dog'
Para evitar olhar para dentro /proc, /sys..., use -xdeve especifique os sistemas de arquivos nos quais deseja pesquisar:
LC_ALL=C find / /home -xdev -type f -exec grep -i 'the brown dog' /dev/null {} +
Ou remova os caminhos que você deseja excluir explicitamente:
LC_ALL=C find / \( -path /dev -o -path /proc -o -path /sys \) -prune -o \
-type f -exec grep -i 'the brown dog' /dev/null {} +