Como percorrer todos os arquivos nos diretórios atuais e subdiretórios para encontrar uma string?

Como percorrer todos os arquivos nos diretórios atuais e subdiretórios para encontrar uma string?

Olá, estou tentando percorrer um diretório e todos os seus subdiretórios para encontrar a string 'foo' em todos os arquivos, por exemplo. Quero então exibir os nomes dos arquivos (incluindo o caminho completo) de todos os arquivos que os contêm.

O sistema operacional é unix e usa shell bash.

Qualquer sugestão seria apreciada. Obrigado

Responder1

Você pode usar um recursivo grep. No GNU grep, pelo menos, essa é a -Ropção:

grep -R foo /path/to/parent/directory

Se você usar um caminho completo, como acima, por exemplo, /home/callsign223/foo/todos os arquivos serão mostrados com seus caminhos qualificados. E se você quiser ver apenas os nomes dos arquivos, não as linhas correspondentes, você pode usar -lpara imprimir apenas o nome do arquivo:

grep -lR foo /path/to/parent/directory

Observe que a -Ropção não é portátil e não é suportada por todas grepas implementações.

Responder2

se grep -Rnão for uma opção, você poderá usar findpara executar grepem cada arquivo:

find ./ -type f -exec grep -Hni "some-string" {} ';'

Responder3

Algo que funcionaria em todos os sistemas Unix atuais é usar findpara localizar os arquivos e, em seguida, grepidentificar os arquivos que contêm a string foo:

find . -type f -exec grep -l -F -e 'foo' {} +

O comando acima encontraria todos os arquivos regulares no diretório atual ou abaixo dele. Para lotes de arquivos encontrados, grepseria chamado para localizar a string foo. Ao localizar a string em um arquivo, grepgera o nome do caminho do arquivo imediatamente e continua com o próximo arquivo sem ler mais do arquivo atual.

  • Usamos -lpara grepparar e relatar o nome do arquivo na primeira linha que corresponde ao padrão fornecido. Isso acelera o processamento, ignorando o bit do arquivo após o primeiro acesso.
  • Usamos -Fpara fazer com que grepo padrão seja considerado uma string em vez de uma expressão regular. Isso potencialmente acelera o processamento ao não tentar desfazer correspondências de expressões regulares e nos permite combinar strings que se parecem com expressões regulares.
  • Usamos -ecom o padrão fornecido, caso comece com um travessão. Isso não acontece neste caso, mas substituir essa string estática foopor uma variável introduziria a possibilidade de correspondência com um padrão que começa com um travessão, o que, portanto, seria confundido com uma opção de linha de comando.

No entanto, uma lista de nomes de arquivos geralmente não é boa. Você provavelmente gostaria de fazer algo com esses arquivos. Nesse caso, você faria isso como parte do utilitário findexecutado por meio de -exec:

find . -type f -exec sh -c '
    for pathname do
        grep -q -F -e "foo" "$pathname" || continue
        # Do something with "$pathname" here
    done' sh {} +

Aqui chamamos um pequeno script em linha para processar arquivos encontrados em lotes. Verificamos cada arquivo individualmente em busca da string fooe ignoramos os arquivos que não contêm a string. Onde adicionei um comentário no script in-line, você processaria o arquivo referenciado por "$pathname".

Você também pode escrever o acima findexecutando grepseparadamente antes de chamar o script in-line:

find . -type f -exec grep -q -F -e 'foo' {} \; -exec sh -c '
    for pathname do
        # Do something with "$pathname" here
    done' sh {} +

Observe como o primeiro -execatua como um teste no arquivo atual antes de chamar sh -cos arquivos que passaram nesse teste.

Responder4

Acredito que o ackutilitário fará exatamente o que você está procurando. Ele já pode estar instalado em seu sistema. Caso contrário, ele pode ser baixado emhttps://beyondgrep.com/.

Um dos recursos interessantes acké que ele ignora arquivos binários por padrão e pode receber opções de linha de comando para restringir os tipos de arquivos pesquisados ​​por algum filtro prescrito ou por tipo de arquivo (por exemplo, por linguagem de programação: --type=ccirá pesquisar .c, .h, .xsarquivos, --type=awkirá pesquise quaisquer arquivos que correspondam /awk/na primeira linha). Esses tipos também podem ser estendidos pelo usuário na linha de comando ou de forma mais permanente no ~/.ackrcarquivo.

informação relacionada