Estou tentando encontrar uma maneira de verificar todo o meu sistema Linux em busca de todos os arquivos que contêm uma sequência específica de texto. Só para esclarecer, estou procurando texto dentro do arquivo, não no nome do arquivo.
Quando eu estava pesquisando sobre 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 exibir todos os arquivos do sistema.
Isso está próximo da maneira correta de fazer isso? Se não, como devo? Essa capacidade de encontrar seqüências de texto em arquivos seria extraordinariamente útil para alguns projetos de programação que estou realizando.
.
um como curinga de um caractere, entre outros. Meu conselho é sempre usar o fgrep ou o egrep.-H
por-l
(e talvezgrep
porfgrep
). Para excluir arquivos com certos padrões de nomes, você usariafind
de uma maneira mais avançada. Vale a pena aprender a usarfind
, no entanto. Apenasman find
.find … -exec <cmd> +
é mais fácil de digitar e mais rápido quefind … -exec <cmd> \;
. Funciona apenas se<cmd>
aceitar qualquer número de argumentos de nome de arquivo. A economia no tempo de execução é especialmente grande se<cmd>
for lenta para iniciar como scripts Python ou Ruby.grep "pattern" path/*.txt
Respostas:
Faça o seguinte:
-r
ou-R
é recursivo,-n
é o número da linha e-w
significa combinar a palavra inteira.-l
(L minúsculo) pode ser adicionado para fornecer apenas o nome do arquivo correspondente.Juntamente com estes,
--exclude
,--include
,--exclude-dir
bandeiras poderiam ser usados para pesquisa eficiente:Isso pesquisará apenas os arquivos que possuem extensões .c ou .h:
Isso excluirá a pesquisa de todos os arquivos que terminam com a extensão .o:
Para diretórios, é possível excluir um diretório específico através do
--exclude-dir
parâmetro Por exemplo, isso excluirá os dirs dir1 /, dir2 / e todos eles correspondentes * .dst /:Isso funciona muito bem para mim, para atingir quase o mesmo objetivo que o seu.
Para mais opções, verifique
man grep
.fonte
r
opção é preguiçosa (percorre a profundidade primeiro, do que para após o primeiro diretório), enquantoR
é gananciosa (percorre a árvore inteira corretamente).R
ptr
atravessará diretórios corretamente, masR
seguirá links simbólicos.Você pode usar
grep -ilR
:i
significa ignorar maiúsculas e minúsculas (opcional no seu caso).R
significa recursivo.l
significa "mostrar o nome do arquivo, não o resultado em si"./
significa começar na raiz da sua máquina.fonte
-i
processo diminui bastante a velocidade, portanto, não o use se não for necessário. Teste-o em um determinado diretório e generalize. Deve ser concluído em alguns minutos. Eu acho que uma expressão regular tornaria mais lenta. Mas meus comentários são baseados em suposições, sugiro que você o testetime
na frente da linha./*
significa isso. Enfim, eu apenas testei e notei que simplesmente/
funciona.fgrep is the same as grep -F -> Interpret PATTERN as a list of fixed strings
.grep -Ril "text-to-find-here" ~/sites/
ou usar. para o diretório atualgrep -Ril "text-to-find-here" .
Você pode usar ack . É como grep para código fonte. Você pode digitalizar todo o seu sistema de arquivos com ele.
Apenas faça:
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-5 vezes mais rápido que ele e até ignora os padrões de um
.gitignore
arquivo.fonte
Você pode usar:
O
r
significa recursivo e, portanto, pesquisará o caminho especificado e também seus subdiretórios. Isso informará o nome do arquivo e imprimirá a linha no arquivo em que a string aparece.Ou um comando semelhante ao que você está tentando (exemplo:) para pesquisar em todos os arquivos javascript (* .js):
Isso imprimirá as linhas nos arquivos em que o texto aparece, mas não imprime o nome do arquivo.
Além deste comando, também podemos escrever: grep -rn "String para pesquisar" / path / to / directory / ou / file -r: pesquisa recursiva n: o número da linha será mostrado para correspondências
fonte
Você pode usar isto:
fonte
Lista de nomes de arquivos que contêm um determinado texto
Primeiro de tudo, acredito que você usou em
-H
vez de-l
. Além disso, você pode tentar adicionar o texto entre aspas, seguido de{} \
.Exemplo
Digamos que você esteja procurando por arquivos que contenham texto específico "Licença Apache" dentro de seu diretório. Ele exibirá resultados um pouco semelhantes aos abaixo (a saída será diferente com base no conteúdo do diretório).
Remover distinção entre maiúsculas e minúsculas
Mesmo se você não usar o caso como "texto" vs "TEXTO", poderá usar a
-i
opção para ignorar o caso. Você pode ler mais detalhes aqui .Espero que isso ajude você.
fonte
find
passará todos os caminhos que encontrar para o comandogrep -l "text-to-find-here" <file found>"
. Você pode adicionar restrições ao nome do arquivo, por exemplo,find / -iname "*.txt"
para pesquisar apenas em arquivos que extremidades de nome em.txt
-iname
faz distinção entre maiúsculas e minúsculas, o que significa que também encontraria arquivos .TXT, por exemplo, além de TxT e TXt e assim por diante.grep
( GNU ou BSD )Você pode usar a
grep
ferramenta para pesquisar recursivamente a pasta atual, como:Nota:
-r
- Pesquise recursivamente subdiretórios.Você também pode usar a sintaxe globbing para pesquisar em arquivos específicos, como:
Nota: Ao usar a opção globbing (
**
), ele verifica todos os arquivos recursivamente com extensão ou padrão específico. Para habilitar essa sintaxe, execute:shopt -s globstar
. Você também pode usar**/*.*
para todos os arquivos (excluindo oculto 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
find
sintaxe como:Como alternativa, use
ripgrep
.ripgrep
Se você estiver trabalhando em projetos maiores ou em arquivos grandes, deve usar
ripgrep
, como:Confira os documentos, as etapas de instalação ou o código-fonte na página do projeto GitHub .
É muito mais rápido do que qualquer outra ferramenta como o GNU / BSD
grep
,ucg
,ag
,sift
,ack
,pt
ou similar, uma vez que é construído em cima do motor de regex de Rust que usa autômatos finitos, SIMD e otimizações literais agressivos para tornar a busca muito rápido.Ele suporta padrões de ignorar especificados em
.gitignore
arquivos, para que um único caminho de arquivo possa ser comparado com 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
- Pesquise as palavras inteiras (ao contrário da correspondência parcial de palavras).-n
- Mostre a linha do seu jogo.-C
/--context
(por exemplo-C5
) - Aumenta o contexto, para que você veja o código ao redor.--color=auto
- Marque o texto correspondente.-H
- Exibe o nome do arquivo onde o texto é encontrado.-c
- Exibe contagem de linhas correspondentes. Pode ser combinado com-H
.fonte
Se o seu
grep
não suporta pesquisa recursiva, você pode combinarfind
comxargs
:Acho isso mais fácil de lembrar do que o formato
find -exec
.Isso produzirá o nome do arquivo e o conteúdo da linha correspondente, por exemplo
Sinalizadores opcionais que você pode adicionar
grep
:-i
- pesquisa sem distinção entre maiúsculas e minúsculas-l
- apenas gera o nome do arquivo onde a correspondência foi encontrada-h
- apenas gera a linha correspondente (não o nome do arquivo)fonte
grep 'text-to-find-here'
sem nome de arquivo, sefind
não encontrar nada. Isso irá travar e aguardar a entrada do usuário! Adicione--no-run-if-empty
como uma opção paraxargs
.find … -exec grep … +
. Se você insistir em usar find junto com xargs, use-print0
e-0
.i
: Ignore as distinções entre maiúsculas e minúsculas nos arquivos PATTERN e de entrada.n
: Prefixe cada linha de saída com o número da linha com base em 1 em seu arquivo de entrada.s
: Suprime mensagens de erro sobre arquivos inexistentes ou ilegíveis.r
: Leia todos os arquivos em cada diretório, recursivamente.fonte
Há um novo utilitário chamado The Silversearcher
Ele trabalha em estreita colaboração com o Git e outros VCS. Então você não terá nada em um .git ou outro diretório.
Você pode simplesmente usar
E fará a tarefa para você!
fonte
Se usando find como no seu exemplo, melhor adicionar
-s
(--no-messages
) paragrep
, e2>/dev/null
no final do comando para lotes Evitar de permissão negada mensagens emitidas pelogrep
efind
:O find é a ferramenta padrão para pesquisar arquivos - combinada com grep ao procurar texto específico - em plataformas semelhantes ao Unix. Ocomando find é frequentemente combinado com xargs , a propósito.
Existem ferramentas mais rápidas e fáceis para o mesmo objetivo - veja abaixo. É melhor experimentá-los, desde que estejam disponíveis em sua plataforma , é claro:
Alternativas mais rápidas e fáceis
RipGrep - ferramenta de busca mais rápida:
O pesquisador de prata :
ack :
Nota: Você também pode adicionar
2>/dev/null
esses comandos para ocultar muitas mensagens de erro.Aviso : a menos que você realmente não possa evitá-lo, não procure em '/' (o diretório raiz) para evitar uma pesquisa longa e ineficiente! Portanto, nos exemplos acima, é melhor substituir ' / ' por um nome de subdiretório, por exemplo, "/ home" dependendo de onde você realmente deseja pesquisar ...
fonte
grep
find
, não pesquisa diretamente o interior dos arquivos em busca de texto. E talvez essas ferramentas adicionais sejam úteis para alguns, mas os veteranos e aqueles que estão bem acostumados, por exemplogrep
, não lhes dariam tempo algum (bem, certamente não darei). Mas não estou dizendo que são inúteis.fol
? Não, claro que não; foi chamadodir
(e acredito que ainda é). Pasta é uma coisa inventada para (eu acho) facilidade de uso, embora, neste caso, talvez seja um embuste para usuários menos 'avançados'?Tentar:
fonte
xargs
dessa maneira ... considere isso.echo "file bar.txt has bar" > bar.txt; echo "file foo bar.txt has foo bar" > "foo bar.txt"; echo "You should never see this foo" > foo; find . -name "*.txt" | xargs grep -i foo # ./foo:You should never see this foo
. Oxargs
aqui corresponde ao arquivo ERRADO e NÃO corresponde ao arquivo pretendido. Ou usar umfind .. -print0 | xargs -0 ...
, mas isso é um uso inútil de um tubo ou melhorfind ... -exec grep ... {} +
Use
pwd
para pesquisar em qualquer diretório em que esteja, recorrendo para baixoAtualizar Dependendo da versão do grep que você está usando, você pode omitir
pwd
. Nas versões mais recentes,.
parece ser o caso padrão do grep se nenhum diretório for fornecido assim:grep -rnw -e "pattern"
ou
grep -rnw "pattern"
fará a mesma coisa que acima!
fonte
pwd
não é necessário, pois é o padrão.grep -rnw "pattern"
é suficiente.grep -rnw
e semelhante é o que foi respondido há três anos, não vejo como essa resposta está agregando valor.grep -rnw '/path/to/somewhere/' -e "pattern"
qual é o que você tem aqui. 5 votos após 2,3 milhões de visitas não significa muito.grep
pode ser usado mesmo se não estivermos procurando uma string.Simplesmente correndo,
imprimirá o caminho para todos os arquivos de texto, ou seja, aqueles que contêm apenas caracteres imprimíveis.
fonte
ls
oufind
(para o recursivo)Aqui está a lista de vários comandos que podem ser usados para pesquisar arquivos.
fonte
egrep
é equivalente aogrep -E
e isso significa--extended-regexp
que você pode encontrar mais detalhes aqui unix.stackexchange.com/a/17951/196072O Silver Searcher é uma ferramenta fantástica, mas o ripgrep pode ser ainda melhor.
Ele funciona no Linux, Mac e Windows e foi escrito no Hacker News há alguns meses (isso tem um link para o Blog de Andrew Gallant, que possui um link do GitHub):
Ripgrep - Uma nova ferramenta de pesquisa de linha de comando
fonte
Explicação dos comentários
find é um comando que permite localizar arquivos e outros objetos, 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 objetos de diretório.
fonte
Tentar:
que pesquisará todos os sistemas de arquivos, porque
/
é a pasta raiz.Para a pasta pessoal, use:
Para a pasta atual, use:
fonte
Espero que isso seja útil ...
Expandir
grep
um pouco para fornecer mais informações na saída, por exemplo, para obter o número da linha no arquivo em que o texto está, pode ser feito da seguinte maneira:E se você tem uma idéia de qual é o tipo de arquivo, pode restringir sua pesquisa especificando extensões de tipo de arquivo a serem pesquisadas, nesse caso
.pas
OU.dfm
arquivos:Breve explicação das opções:
.
nofind
especifica no diretório atual.-name
"*.*
": Para todos os arquivos (-name "*.pas
" -o -name "*.dfm
"): Apenas os*.pas
OU*.dfm
arquivos ou especificado com-o
-type f
especifica que você está procurando arquivos-print0
e--null
do outro lado do|
(canal) são os cruciais, passando o nome do arquivo dofind
para ogrep
incorporado noxargs
, permitindo a passagem de nomes de arquivos WITH espaços nos nomes de arquivos, permitindo que o grep trate o caminho e o nome do arquivo como uma sequência, e não dividi-lo em cada espaço.fonte
-name '*.*'
não é o que você diz; não seria capturado em um arquivo chamado 'arquivo' porque o padrão não é igual a isso (não .ext);*
seria no entanto (bem. arquivos de lado). Mas há outra coisa: se você deseja todos os arquivos, por que se preocupar em especificar um nome de arquivo em primeiro lugar? Nenhum outro comentário - exceto que é bom saber que ainda existem pessoas que não usam a 'pasta' da terminologia da MS (o que realmente depois de dizer o suficiente eu não acrescentaria, mas eu queria destacar a declaração levemente incorreta que você fez com nomes de arquivo - assim como redundância / inutilidade no caso de 'todos').Um Simple
find
pode ser útil. alias no seu~/.bashrc
arquivo:Inicie um novo terminal e faça o seguinte:
fonte
Eu escrevi um script Python que faz algo semelhante. É assim que se deve usar esse script.
O primeiro argumento,,
path
é o diretório no qual pesquisaremos recursivamente. O segundo argumento,,pattern_to_search
é uma expressão regular que queremos pesquisar em um arquivo. Usamos o formato de expressão regular definido na biblioteca Pythonre
. Nesse script, o.
também corresponde a nova linha.O terceiro argumento,
file_pattern
,, é opcional. Essa é outra expressão regular que funciona em um nome de arquivo. Somente 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
contendoPool(
seguida por palavraAdaptor
, faça o seguinte,E pronto, gera o caminho dos arquivos correspondentes e o número da linha em que a correspondência foi encontrada. Se mais de uma correspondência for encontrada, cada número de linha será anexado ao nome do arquivo.
fonte
Se você deseja usar estritamente
find
, usefind + grep
:find /path/to/somewhere/ -type f -exec grep -nw 'textPattern' {} \;
passos:
1. Use
find
para procurar arquivos,2.Then executar
grep
em todos eles.Isso pode dar a você o poder de
find
encontrar arquivos.Use
-name Pattern
se você quisergrep
apenas determinados arquivos:find /path/to/somewhere/ -type f -name \*.cpp -exec grep -nw 'textPattern' {} \;
Você pode brincar com ele e usar diferentes opções
find
para melhorar ou restringir sua pesquisa de arquivos.fonte
Usar:
Isso informará quantas cópias do seu padrão existem em cada um dos arquivos no diretório atual.
fonte
grep é seu bom amigo para conseguir isso.
Se você não se importa com o caso do texto a ser encontrado, use:
fonte
-
s na string de pesquisa, você deve passar--
primeiro para o grep; isso pode causar efeitos colaterais interessantes de outra maneira!Estou fascinado por como o grep é simples com 'rl':
Funciona perfeitamente ...
fonte
.txt
). Ou existe uma maneira de fazer isso?Para procurar a sequência e gerar apenas essa linha com a sequência de pesquisa:
por exemplo:
Para exibir o nome do arquivo que contém a string de pesquisa:
por exemplo:
fonte
find … -exec grep 'str' {} \;
(se você precisar usáfind
-lo).find
espaços contidos ... você pudesse acabar comgrepping
os arquivos errados e / ou com a falta dos arquivos certos. Basta usarfind ... -exec grep ...
se você precisar usarfind
.. mas, neste caso,grep -r ...
é suficiente.Existe uma
ack
ferramenta que faria exatamente o que você está procurando.http://linux.die.net/man/1/ack
Você pode ignorar
-i
a pesquisa que diferencia maiúsculas de minúsculasfonte
Todas as respostas anteriores sugerem grep e find. Mas há outra maneira: use Midnight Commander
É um utilitário gratuito (30 anos, comprovado pelo tempo) que é visual sem ser GUI. Possui inúmeras funções, e encontrar arquivos é apenas uma delas.
fonte
O comando abaixo funcionará bem para esta abordagem:
fonte
find
e entãogrep -r
? Eles são feitos para o mesmo, então isso é redundante.find
.Evite o aborrecimento e instale o ack-grep. Elimina muitos problemas de permissão e cotação.
Em seguida, vá para o diretório que você deseja pesquisar e execute o comando abaixo
fonte