Como faço para encontrar todos os arquivos contendo texto específico no Linux?

Eu estou tentando encontrar uma maneira de verificar todo o meu sistema Linux para todos os arquivos contendo uma seqüência específica de texto. Só para esclarecer, estou procurando por texto dentro do arquivo, não no nome do arquivo.

Quando eu estava pesquisando como fazer isso, me deparei com essa solução duas vezes:

find / -type f -exec grep -H 'text-to-find-here' {} \; 

No entanto, isso não funciona. Parece para mostrar todos os arquivos no sistema.

Isso está perto da maneira correta de fazer isso? Se não, como eu deveria? Essa capacidade de encontrar strings de texto em arquivos seria extraordinariamente útil para alguns projetos de programação que estou fazendo.

Faça o seguinte:

 grep -rnw '/path/to/somewhere/' -e 'pattern' 
  • -r ou -R é recursivo,
  • -n é o número da linha e
  • -w significa coincidir com a palavra inteira.
  • -l (letra minúscula L) pode ser adicionado apenas para dar o nome do arquivo de arquivos correspondentes.

Juntamente com estes, --exclude , --include , --exclude-dir flags podem ser usados ​​para busca eficiente:

  • Isso só pesquisará os arquivos que possuem extensões .c ou .h:

     grep --include=\*.{c,h} -rnw '/path/to/somewhere/' -e "pattern" 
  • Isso excluirá a pesquisa de todos os arquivos que terminem com a extensão .o:

     grep --exclude=*.o -rnw '/path/to/somewhere/' -e "pattern" 
  • Para diretórios, é possível excluir um determinado diretório (s) através --exclude-dir parâmetro --exclude-dir . Por exemplo, isso excluirá as pastas dir1 /, dir2 / e todas elas correspondentes a * .dst /:

     grep --exclude-dir={dir1,dir2,*.dst} -rnw '/path/to/somewhere/' -e "pattern" 

Isso funciona muito bem para mim, para alcançar quase o mesmo propósito como o seu.

Para mais opções, selecione man grep .

Você pode usar grep -ilR :

 grep -Ril "text-to-find-here" / 
  • i significa ignorar caso (opcional no seu caso).
  • R significa recursivo.
  • l significa “mostrar o nome do arquivo, não o resultado em si”.
  • / significa iniciar na raiz da sua máquina.

Você pode usar o ack . É como grep para código-fonte. Você pode escanear todo o seu sistema de arquivos com ele.

Apenas faça:

 ack 'text-to-find-here' 

No seu diretório raiz.

Você também pode usar expressões regulares , especificar o tipo de arquivo etc.


ATUALIZAR

Acabei de descobrir o Silver Searcher , que é como ack, mas 3-5x mais rápido do que ele e até ignora os padrões de um arquivo .gitignore .

Você pode usar:

 grep -r "string to be searched" /path/to/dir 

O r significa recursivo e, portanto, irá procurar no caminho especificado e também em seus subdiretórios. Isto irá dizer-lhe o nome do arquivo, bem como imprimir a linha no arquivo onde a string aparece.

Ou um comando semelhante ao que você está tentando (exemplo:) para pesquisar em todos os arquivos javascript (* .js):

 find . -name '*.js' -exec grep -i 'string to search for' {} \; -print 

Isso imprimirá as linhas nos arquivos onde o texto aparece, mas não imprimirá o nome do arquivo.

Além desse comando, podemos escrever isso também: grep -rn “String para pesquisar” / caminho / para / diretório / ou / arquivo -r: pesquisa recursiva n: o número da linha será mostrado para correspondências

Você pode usar isto:

 grep -inr "Text" folder/to/be/searched/ 

Lista de nomes de arquivos contendo um determinado texto

Primeiro de tudo, acredito que você usou -H vez de -l . Além disso, você pode tentar adicionar o texto dentro de citações seguido por {} \ .

 find / -type f -exec grep -l "text-to-find-here" {} \; 

Exemplo

Digamos que você esteja procurando por arquivos contendo texto específico “Licença Apache” dentro do seu diretório. Ele exibirá resultados um pouco semelhantes aos abaixo (a saída será diferente com base no conteúdo do diretório).

 bash-4.1$ find . -type f -exec grep -l "Apache License" {} \; ./net/java/jvnet-parent/5/jvnet-parent-5.pom ./commons-cli/commons-cli/1.3.1/commons-cli-1.3.1.pom ./io/swagger/swagger-project/1.5.10/swagger-project-1.5.10.pom ./io/netty/netty-transport/4.1.7.Final/netty-transport-4.1.7.Final.pom ./commons-codec/commons-codec/1.9/commons-codec-1.9.pom ./commons-io/commons-io/2.4/commons-io-2.4.pom bash-4.1$ 

Remova a sensibilidade do caso

Mesmo se você não estiver usando o caso como “texto” vs “TEXTO”, você pode usar a opção -i para ignorar o caso. Você pode ler mais detalhes aqui .

Espero que isso ajude você.

Se o seu grep não suporta busca recursiva, você pode combinar find com xargs :

 find / -type f | xargs grep 'text-to-find-here' 

Acho isso mais fácil de lembrar do que o formato para find -exec .

Isso produzirá o nome do arquivo e o conteúdo da linha correspondente, por exemplo

 /home/rob/file:text-to-find-here 

Sinalizadores opcionais que você pode querer adicionar ao grep :

  • -i – pesquisa insensível a maiúsculas e minúsculas
  • -l – apenas exibe o nome do arquivo onde a correspondência foi encontrada
  • -h – apenas exibe a linha correspondente (não o nome do arquivo)
 grep -insr "pattern" * 
  • i : Ignora distinções de maiúsculas e minúsculas no PATTERN e nos arquivos de input.
  • n : Prefixo cada linha de saída com o número de linha baseado em 1 em seu arquivo de input.
  • s : Suprime as mensagens de erro sobre arquivos inexistentes ou ilegíveis.
  • r : Leia todos os arquivos em cada diretório, recursivamente.

grep ( GNU ou BSD )

Você pode usar a ferramenta grep para pesquisar recursivamente a pasta atual, como:

 grep -r "class foo" . 

Nota: -r – Pesquisa recursivamente subdiretórios.

Você também pode usar a syntax globbing para pesquisar arquivos específicos, como:

 grep "class foo" **/*.c 

Nota: Usando a opção globbing ( ** ), ele verifica todos os arquivos recursivamente com extensão ou padrão específico. Para habilitar esta syntax, execute: shopt -s globstar . Você também pode usar **/*.* Para todos os arquivos (excluindo ocultos e sem extensão) ou qualquer outro padrão.

Se você tiver o erro de que seu argumento é muito longo, considere restringir sua pesquisa ou use a syntax de find como:

 find . -name "*.php" -execdir grep -nH --color=auto foo {} ';' 

Como alternativa, use ripgrep .

ripgrep

Se você está trabalhando em projetos maiores ou arquivos grandes, você deve usar o ripgrep , como:

 rg "class foo" . 

Faça check-out dos documentos, etapas de instalação ou código-fonte na página do projeto do GitHub .

É muito mais rápido do que qualquer outra ferramenta como o GNU / BSD grep , ucg , ag , sift , ack , pt ou similar, já que é construída sobre o motor regex da Rust que usa autômatos finitos, SIMD e otimizações literais agressivas para tornar a pesquisa muito rápida .

Ele suporta padrões de ignorar especificados em arquivos .gitignore , portanto, um único caminho de arquivo pode ser comparado a vários padrões glob simultaneamente.


Você pode usar os parâmetros comuns, como:

  • -i – Pesquisa insensível.
  • -I – Ignore os arquivos binários.
  • -w – Procura pelas palavras inteiras (no oposto da correspondência parcial de palavras).
  • -n – Mostra a linha do teu jogo.
  • -C / --context (por exemplo -C5 ) – Aumenta o contexto, então você vê o código circundante.
  • --color=auto – Marque o texto correspondente.
  • -H – Exibe o nome do arquivo onde o texto é encontrado.
  • -c – Exibe a contagem de linhas correspondentes. Pode ser combinado com -H .

Experimentar:

 find . -name "*.txt" | xargs grep -i "text_pattern" 

Use pwd para procurar em qualquer diretório em que estiver, recursing downward

 grep -rnw `pwd` -e "pattern" 

Atualização Dependendo da versão do grep que você está usando, você pode omitir o pwd . Em versões mais recentes parece ser o caso padrão para grep se nenhum diretório é dado assim:

grep -rnw -e "pattern"

ou

grep -rnw "pattern"

fará o mesmo que acima!

Existe um novo utilitário chamado The Silversearcher

 sudo apt install silversearcher-ag 

Trabalha em estreita colaboração com o Git e outros VCS. Então você não vai conseguir nada em um .git ou outro diretório.

Você pode simplesmente usar

 ag -ia "Search query" 

E vai fazer a tarefa para você!

grep pode ser usado mesmo se não estivermos procurando por uma string.

Simplesmente correndo,

 grep -RIl "" . 

irá imprimir o caminho para todos os arquivos de texto, ou seja, aqueles que contêm apenas caracteres imprimíveis.

Aqui estão as várias listas de comandos que podem ser usados ​​para pesquisar arquivos.

 grep "text string to search” directory-path grep [option] "text string to search” directory-path grep -r "text string to search” directory-path grep -r -H "text string to search” directory-path egrep -R "word-1|word-2” directory-path egrep -w -R "word-1|word-2” directory-path 

Como faço para encontrar todos os arquivos contendo texto específico no Linux? (…)

Eu encontrei esta solução duas vezes:

find / -type f -exec grep -H 'text-to-find-here' {} \;


Se estiver usando find como no seu exemplo, é melhor adicionar -s ( --no-messages ) ao grep e 2>/dev/null no final do comando para evitar um monte de Permission denied messages emitidas pelo grep e find :

 find / -type f -exec grep -sH 'text-to-find-here' {} \; 2>/dev/null 

find é a ferramenta padrão para pesquisar arquivos – combinada com o grep ao procurar por um texto específico – em plataformas semelhantes ao Unix. O comando find é frequentemente combinado com xargs , a propósito.

Ferramentas mais rápidas e fáceis existem para o mesmo propósito – veja abaixo. É melhor experimentá-los, desde que estejam disponíveis em sua plataforma , é claro:

Alternativas mais rápidas e fáceis

RipGrep – ferramenta de pesquisa mais rápida em torno de:

 rg 'text-to-find-here' / -l 

O Silver Searcher :

 ag 'text-to-find-here' / -l 

ack :

 ack 'text-to-find-here' / -l 

Nota: Você também pode adicionar 2>/dev/null a esses comandos para ocultar muitas mensagens de erro.


Aviso : a menos que você realmente não possa evitá-lo, não pesquise em ‘/’ (o diretório raiz) para evitar uma pesquisa longa e ineficiente! Assim, nos exemplos acima, é melhor você replace ‘ / ‘ por um nome de subdiretório, por exemplo, “/ home”, dependendo de onde você realmente deseja pesquisar …

Um find simples pode ser útil. alias em seu arquivo ~/.bashrc :

 alias ffind find / -type f | xargs grep 

Inicie um novo terminal e emita:

 ffind 'text-to-find-here' 

Eu escrevi um script Python que faz algo semelhante. É assim que se deve usar esse script.

 ./sniff.py path pattern_to_search [file_pattern] 

O primeiro argumento, path , é o diretório no qual procuraremos recursivamente. O segundo argumento, pattern_to_search , é uma expressão regular que queremos procurar em um arquivo. Usamos o formato de expressão regular definido na biblioteca do Python re . Neste script, o . também corresponde à nova linha.

O terceiro argumento, file_pattern , é opcional. Esta é outra expressão regular que funciona em um nome de arquivo. Apenas os arquivos que correspondem a essa expressão regular serão considerados.

Por exemplo, se eu quiser pesquisar arquivos Python com a extensão py contendo Pool( seguido por palavra Adaptor , eu faço o seguinte,

 ./sniff.py . "Pool(.*?Adaptor" .*py ./Demos/snippets/cubeMeshSigNeur.py:146 ./Demos/snippets/testSigNeur.py:259 ./python/moose/multiscale/core/mumbl.py:206 ./Demos/snippets/multiComptSigNeur.py:268 

E voila, ele gera o caminho dos arquivos correspondentes e o número da linha na qual a correspondência foi encontrada. Se mais de uma correspondência for encontrada, cada número de linha será anexado ao nome do arquivo.

 find /path -type f -exec grep -l "string" {} \; 

Explicação dos comentários

find é um comando que permite encontrar arquivos e outros objects como diretórios e links em subdiretórios de um determinado caminho. Se você não especificar uma máscara que os nomes de arquivos devem atender, ele enumera todos os objects de diretório.

 -type f specifies that it should proceed only files, not directories etc. -exec grep specifies that for every found file, it should run grep command, passing its filename as an argument to it, by replacing {} with the filename 

Experimentar:

 find / -type f -exec grep -H 'text-to-find-here' {} \; 

que pesquisará todos os filesystems, porque / é a pasta raiz.

Para uso da pasta inicial:

 find ~/ -type f -exec grep -H 'text-to-find-here' {} \; 

Para uso da pasta atual:

 find ./ -type f -exec grep -H 'text-to-find-here' {} \; 

Espero que isso seja de ajuda …

Expandir um pouco o grep para dar mais informações na saída, por exemplo, para obter o número da linha no arquivo onde o texto está pode ser feito da seguinte forma:

 find . -type f -name "*.*" -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searthtext" 

E se você tem uma idéia do tipo de arquivo que você pode restringir a sua pesquisa, especificando as extensões de tipo de arquivo para procurar, neste caso .pas ou arquivos .dfm :

 find . -type f \( -name "*.pas" -o -name "*.dfm" \) -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searchtext" 

Breve explicação das opções:

  1. . in the find especifica a partir do diretório atual.
  2. -name*.* “: para todos os arquivos (-name ” *.pas ” -o -name ” *.dfm “): Somente os *.pas OR *.dfm , OR especificados com -o
  3. -type f especifica que você está procurando por arquivos
  4. -print0 e --null do outro lado do | (pipe) são os cruciais, passando o nome do arquivo do find para o grep embutido no xargs , permitindo a passagem de nomes de arquivos com espaços nos nomes dos arquivos, permitindo ao grep tratar o caminho e o nome do arquivo como uma string e não quebrá-lo em cada espaço.

O Silver Searcher é uma excelente ferramenta, mas o ripgrep pode ser ainda melhor.

Ele funciona em Linux, Mac e Windows, e foi escrito no Hacker News alguns meses atrás (isso tem um link para o blog de Andrew Gallant que tem um link do GitHub):

Ripgrep – Uma nova ferramenta de pesquisa de linha de comando

Usar:

 grep -c Your_Pattern * 

Isso informará quantas cópias de seu padrão estão em cada um dos arquivos no diretório atual.

O comando abaixo funcionará bem para essa abordagem:

 find ./ -name "file_pattern_name" -exec grep -r "pattern" {} \; 

Para procurar a string e produzir apenas essa linha com a string de pesquisa:

 for i in $(find /path/of/target/directory -type f); do grep -i "the string to look for" "$i"; done 

por exemplo:

 for i in $(find /usr/share/applications -type f); \ do grep -i "web browser" "$i"; done 

Para exibir o nome do arquivo que contém a string de pesquisa:

 for i in $(find /path/of/target/directory -type f); do if grep -i "the string to look for" "$i" > /dev/null; then echo "$i"; fi; done; 

por exemplo:

 for i in $(find /usr/share/applications -type f); \ do if grep -i "web browser" "$i" > /dev/null; then echo "$i"; \ fi; done; 

grep é seu bom amigo para conseguir isso.

 grep -r   

se você não se importa com o caso do texto para encontrar, em seguida, use

 grep -ir   

Evite o incômodo e instale o ack-grep. Elimina muitos problemas de permissão e cotação.

 apt-get install ack-grep 

Em seguida, vá para o diretório que você deseja pesquisar e execute o comando abaixo

 cd / ack-grep "find my keyword" 

Existe uma ferramenta que faz exatamente o que você está procurando.

http://linux.die.net/man/1/ack

 ack -i search_string folder_path/* 

Você pode ignorar -i para pesquisa sensível a maiúsculas e minúsculas

Eu sou fascinado por quão simples o grep faz com ‘rl’

 grep -rl 'pattern_to_find' /path/where/to/find -r to find recursively file / directory inside directories.. -l to list files matching the 'pattern' 

Use ‘-r’ sem ‘l’ para ver os nomes dos arquivos seguidos pelo texto no qual o padrão é encontrado !

 grep -r 'pattern_to_find' /path/where/to/find 

Funciona simplesmente perfeito ..

Espero que ajude!

 grep -Erni + "text you wanna search" 

O comando pesquisará recursivamente em todos os arquivos e diretórios do diretório atual e imprimirá o resultado.

Nota: se a sua saída do grep não estiver colorida, você pode alterá-la usando o alias grep = ‘grep –color = always’ no seu arquivo src do shell

Tente isto:

 find . | xargs grep 'word' -sl