Editar: Se você tiver utilitários GNU, veja a resposta de Gilles para um método usando habilidades de recursão do GNU grep
que é muito mais simples que a abordagem find
. Se você quiser apenas exibir nomes de arquivos, você ainda desejará adicionar a opção -l
conforme descrito abaixo.
Use grep -l word
para imprimir apenas os nomes dos arquivos que contêm uma correspondência.
Se você quiser encontrar todos os arquivos no sistema de arquivos que terminam em .sh
, começando na raiz /
, então find
é a ferramenta mais apropriada.
A recomendação mais portátil e eficiente é:
find / -type f -name '*.sh' -exec grep -l word {} + 2>/dev/null
Isso é tão legível quanto possível e não é difícil de analisar se você entender a semântica por trás de cada um dos componentes.
-
find /
: executarfind
iniciando na raiz do sistema de arquivos,/
-
-type f
: apenas corresponde a arquivos regulares -
-name '*.sh'
: ... e apenas correspondem aos arquivos cujos nomes terminam em.sh
-
-exec ... {} +
: comando de execução especificado em...
em arquivos correspondentes em grupos, em que{}
é substituído pelos nomes de arquivos no grupo. A idéia é executar o comando em tantos arquivos quanto possível dentro dos limites do sistema (ARG_MAX
). A eficiência da forma{} +
vem da minimização do número de vezes que o comando...
deve ser chamado, maximizando o número de arquivos passados para cada chamada de...
. -
grep -l word {}
: onde o{}
é o mesmo{}
repetido acima e é substituído por nomes de arquivos. Como explicado anteriormente,grep -l
imprime os nomes dos arquivos que contêm uma correspondência paraword
. -
2>/dev/null
: oculta as mensagens de erro (tecnicamente, redirecione o erro padrão para o buraco negro que é/dev/null
). Isso ocorre por motivos estéticos e práticos, pois a execução defind
em/
provavelmente resultará em resmas de mensagens de "permissão negada" às quais você pode não se importar para arquivos que você não tem permissão para ler e diretórios que você não tem permissão para atravessar.
Existem alguns problemas com as sugestões recebidas e publicadas na sua pergunta. Ambos
grep word 'find / -name \*.sh 2>/dev/null
e
find / -name "*.sh" 2>/dev/null | xargs grep word
falha em arquivos com espaços em branco em seus nomes. É melhor evitar colocar nomes de arquivos na substituição do comando. O primeiro tem o problema adicional de possivelmente entrar no limite de ARG_MAX. O segundo é próximo do que eu sugiro, mas não há uma boa razão para usar xargs
aqui, sem mencionar que o uso seguro e correto de xargs
requer o sacrifício da portabilidade para algumas opções somente GNU ( find -print0 | xargs -0
).