Como encontro todos os arquivos que contêm texto específico no Linux?


5259

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.


21
lembre-se de que o grep interpretará qualquer .um como curinga de um caractere, entre outros. Meu conselho é sempre usar o fgrep ou o egrep.
Walter Tross 28/10

10
de qualquer forma, você estava quase lá! Apenas substitua -Hpor -l(e talvez greppor fgrep). Para excluir arquivos com certos padrões de nomes, você usaria findde uma maneira mais avançada. Vale a pena aprender a usar find, no entanto. Apenas man find.
Walter Tross

6
find … -exec <cmd> +é mais fácil de digitar e mais rápido que find … -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.
hagello

Para pesquisar de forma não recursiva em um determinado caminho, o comando é `grep --include = *. Txt -snw" padrão "thepath / *.
Stéphane Laurent

@ StéphaneLaurent Acho que você está complicando demais. Apenas digagrep "pattern" path/*.txt
fedorqui 'Então pare de prejudicar'

Respostas:


9523

Faça o seguinte:

grep -rnw '/path/to/somewhere/' -e 'pattern'
  • -rou -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-dirbandeiras poderiam ser usados para pesquisa eficiente:

  • Isso pesquisará apenas 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 terminam com a extensão .o:

    grep --exclude=*.o -rnw '/path/to/somewhere/' -e "pattern"
    
  • Para diretórios, é possível excluir um diretório específico através do --exclude-dirparâmetro Por exemplo, isso excluirá os dirs dir1 /, dir2 / e todos eles correspondentes * .dst /:

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

Isso funciona muito bem para mim, para atingir quase o mesmo objetivo que o seu.

Para mais opções, verifique man grep.


74
use --exclude. como "grep -rnw --exclude = *. o 'diretório' -e" padrão "
rakib_

98
vale a pena notar: parece que a ropção é preguiçosa (percorre a profundidade primeiro, do que para após o primeiro diretório), enquanto Ré gananciosa (percorre a árvore inteira corretamente).
Eliran Malka

5
grep -rnw "String que eu estava procurando" fez o que eu precisava. Obrigado!
precisa saber é o seguinte

33
Nota (especialmente para iniciantes): As aspas no comando acima são importantes.
madD7

69
@Eliran Malka Rpt ratravessará diretórios corretamente, mas Rseguirá links simbólicos.
bzeaman

1499

Você pode usar grep -ilR:

grep -Ril "text-to-find-here" /
  • 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.

85
Com base na minha experiência, o -iprocesso 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 teste timena frente da linha.
fedorqui 'ASSIM, pare de prejudicar'

4
Sim, /*significa isso. Enfim, eu apenas testei e notei que simplesmente /funciona.
fedorqui 'ASSIM, pare de prejudicar'

10
Se você não estiver pesquisando usando um regex, poderá usar o fgrep no lugar do grep na maioria dos sistemas.
markle976

8
Sim @ markle976, na verdade do homem grep: fgrep is the same as grep -F -> Interpret PATTERN as a list of fixed strings.
fedorqui 'SO parar de prejudicar'

17
Você pode substituir / com o caminho do diretório grep -Ril "text-to-find-here" ~/sites/ou usar. para o diretório atualgrep -Ril "text-to-find-here" .
Preto

329

Você pode usar ack . É como grep para código fonte. Você pode digitalizar 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-5 vezes mais rápido que ele e até ignora os padrões de um .gitignorearquivo.


57
Muito útil, simples e rápido. Aviso: "Nas distribuições derivadas do Debian, o ack é empacotado como" ack-grep "porque o" ack "já existia" (em beyondgrep.com/install ). Você pode acabar correndo um conversor de código Kanji nesses Linuxes ...
Jose_GD

11
ack ou ack-grep tem bons destaques, mas encontrar + grep quando apropriado utilizado é muito melhor em desempenho
Sławomir Lenart

14
Observe que o ripgrep é mais rápido do que qualquer outra coisa mencionada aqui, incluindo o Silver Searcher e o grep. Veja esta postagem no blog para obter provas.
Radon Rosborough 14/10

194

Você pode usar:

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

O rsignifica 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):

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

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


1
Thanx pela versão encontrada. Minha versão grep (busybox para NAS) não tem a opção -r, eu realmente precisava de outra solução!
jc

3
Obrigado pela versão 'find'! É tão importante poder filtrar por ' .js' ou ' .txt', etc. Ninguém quer passar horas esperando o grep terminar de pesquisar todos os vídeos com vários gigabytes das últimas férias em família, mesmo que o comando seja mais fácil de digitar.
Mightypile 16/08/19

melhor grep que a versão aceita, porque aceitou não procurar meias palavras
waza123

114

Você pode usar isto:

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

12
mais fácil, detalhado, recursivo e sem distinção entre maiúsculas e minúsculas. afirmativo.
Francesco Casula

se você adicionar A3 é ainda melhor
albanx

73

Lista de nomes de arquivos que contêm um determinado texto

Primeiro de tudo, acredito que você usou em -Hvez de -l. Além disso, você pode tentar adicionar o texto entre aspas, seguido de {} \.

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

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).

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$ 

Remover distinção entre maiúsculas e minúsculas

Mesmo se você não usar o caso como "texto" vs "TEXTO", poderá usar a -iopção para ignorar o caso. Você pode ler mais detalhes aqui .

Espero que isso ajude você.


2
Qual é o que esse comando faz: findpassará todos os caminhos que encontrar para o comando grep -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
Mene

1
@Auxiliary - incluiu uma amostra de saída para evitar qualquer confusão para os leitores.
Lkal7

2
@Mene É um estado verdadeiramente triste que o comentário do Auxiliar tenha mais votos do que o seu ... mesmo que o comentário seja de 2014 e o seu seja de 2017, o comentário dele tem 6 quando deveria ter exatamente 0 e o seu tinha apenas um (agora dois) isn é algo que eu gostaria de acreditar.
Pryftan

@Mene O que foi dito não -inamefaz 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.
Pryftan

66

grep( GNU ou BSD )

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

grep -r "class foo" .

Nota: -r- Pesquise recursivamente subdiretórios.

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

grep "class foo" **/*.c

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 findsintaxe como:

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

Como alternativa, use ripgrep.

ripgrep

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

rg "class foo" .

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, ptou 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 .gitignorearquivos, 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.

1
Eu também acho útil globbing estendido. Mas lembre-se de que, se houver realmente um grande número de arquivos, você poderá receber um erro "A lista de argumentos é muito longa". (Globbing simples também é propenso a esse tipo de erro).
Yoory N.

2
Ao inalar um sistema de arquivos inteiro, o rg será muito menos doloroso do que quase qualquer outra ferramenta.
Lk

55

Se o seu grepnão suporta pesquisa recursiva, você pode combinar findcom xargs:

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

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

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

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)

3
Isso é equivalente a grep 'text-to-find-here'sem nome de arquivo, se findnão encontrar nada. Isso irá travar e aguardar a entrada do usuário! Adicione --no-run-if-emptycomo uma opção para xargs.
hagello

3
Essa combinação de localização e xargs não funciona conforme o esperado, se os nomes de arquivos ou diretórios contiverem espaços (caracteres que xargs interpreta como separadores). Use find … -exec grep … +. Se você insistir em usar find junto com xargs, use -print0e -0.
hagello

43
grep -insr "pattern" *
  • 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.

3
Você pode explicar como sua resposta melhora as outras respostas ou como é suficientemente diferente delas?
26616 Amos M. Carpenter

não é muito complexo de lembrar, abrangerá todos os padrões (distinção entre maiúsculas e minúsculas -> desativado, inclui nomes de arquivos e número de linha e fará pesquisa recursiva etc.) e usar "*" no final pesquisará todos os diretórios (não é necessário especificar nenhum caminho ou nome do diretório).
enfinet

Desculpe, eu deveria ter sido mais claro: seria ótimo se você pudesse incluir essa explicação em sua resposta. Tal como está, especialmente com tantas outras respostas semelhantes, é difícil ver em uma resposta tão curta qual seria o benefício de experimentá- la sobre a resposta aceita ou uma das que já foram votadas.
26616 Amos M. Carpenter

6
@ AmosM.Carpenter Uma coisa que eu amo nessa resposta é apontar o argumento suprimir, que pode ajudar a filtrar o ruído que não importa para obter os resultados que realmente queremos. O Grep imprime erros como "Função não implementada", "Argumento inválido", "Recurso indisponível" etc. etc. em determinados "arquivos".
LeetNightshade

@leetNightshade: Estou supondo que você esteja me enviando seu comentário porque pedi uma explicação sobre o esparso post original. Por favor, veja a grande revisão de Fabio para que meus comentários anteriores façam sentido.
Amos M. Carpenter

39

Há um novo utilitário chamado The Silversearcher

sudo apt install silversearcher-ag

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

ag "Search query"

E fará a tarefa para você!


35

Como encontro todos os arquivos que contêm texto específico no Linux? (...)

Me deparei com esta solução duas vezes:

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


Se usando find como no seu exemplo, melhor adicionar -s( --no-messages) para grep, e 2>/dev/nullno final do comando para lotes Evitar de permissão negada mensagens emitidas pelo grepe find:

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

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:

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

O pesquisador de prata :

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

ack :

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

Nota: Você também pode adicionar 2>/dev/nullesses 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 ...


'find é a ferramenta padrão para pesquisar arquivos contendo texto específico em plataformas semelhantes a Unix' parece bastante ambíguo para mim. Mesmo além de recursivo 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 exemplo grep, não lhes dariam tempo algum (bem, certamente não darei). Mas não estou dizendo que são inúteis.
Pryftan

".... contendo texto específico ...": esta parte da frase não era precisa (porque não é a mesma que lida com essa parte da pesquisa). Editado. Obrigado.
Bludzee

Feliz por ajudar! A única coisa mais rápida é mudar a pasta de palavras para diretório, mas sei que é uma cruzada minha que nunca vencerei completamente. Não
desista

Por que não "diretório" em vez de "pasta", mas por quê? Por favor, compartilhe sua "cruzada"!
Bludzee

Estou dizendo para usar o diretório! Referindo-se a: é melhor substituir '/' por um nome de subpasta E é uma irritação minha .. esp, já que até o Windows costumava chamá-lo de 'diretório'. Ah ... talvez você tenha entendido. Por quê? Bem, porque é assim que se chama. Também é chamado assim no nível do sistema de arquivos. E olhe para o seguinte: foi chamado (para DOS) fol? Não, claro que não; foi chamado dir(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'?
Pryftan

29

Tentar:

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

5
Este é realmente um excelente exemplo de quando NÃO usar xargsdessa 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. O xargsaqui corresponde ao arquivo ERRADO e NÃO corresponde ao arquivo pretendido. Ou usar um find .. -print0 | xargs -0 ..., mas isso é um uso inútil de um tubo ou melhorfind ... -exec grep ... {} +
shalomb

29

Use pwdpara pesquisar em qualquer diretório em que esteja, recorrendo para baixo

grep -rnw `pwd` -e "pattern"

Atualizar 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!


3
O uso pwdnão é necessário, pois é o padrão. grep -rnw "pattern"é suficiente.
fedorqui 'Então, pare de prejudicar'

e de fato o grep -rnwe semelhante é o que foi respondido há três anos, não vejo como essa resposta está agregando valor.
fedorqui 'Então pare de prejudicar'

A resposta selecionada não mostram o padrão padrão e 5 povos parecia ter encontrado útil
mahatmanich

O que você quer dizer com "padrão padrão"? A resposta aceita contém 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.
fedorqui 'Então pare de prejudicar' 14/12

Concordo :-) o que estava faltando na resposta original é o caso de uso em que você não precisa fornecer um caminho ou pesquisar o diretório atual recursivamente, o que não se reflete na resposta aceita. Portanto, foi uma boa experiência de aprendizado sobre grep um pouco mais fundo.
mahatmanich

19

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

Simplesmente correndo,

grep -RIl "" .

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


2
Eu não vejo como isso é melhor do que usar um mero lsou find(para o recursivo)
fedorqui 'SO pare de prejudicar'

17

Aqui está a lista de vários 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

5
o que isso está adicionando às respostas existentes?
fedorqui 'Então, pare de prejudicar'

@fedorqui egrepé equivalente ao grep -Ee isso significa --extended-regexpque você pode encontrar mais detalhes aqui unix.stackexchange.com/a/17951/196072
omerhakanbilici


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

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.

-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

15

Tentar:

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

que pesquisará todos os sistemas de arquivos, porque / é a pasta raiz.

Para a pasta pessoal, use:

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

Para a pasta atual, use:

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

Talvez os detalhes sobre as diferenças de pastas sejam óbvios para muitos ... mas também muito úteis para iniciantes. +1
nilon 17/10/16

1
o que isso está adicionando às respostas existentes?
fedorqui 'Então, pare de prejudicar'

Pode chamar de minha cruzada, mas a palavra é 'diretório'. Este não é o Windows (que costumava usar o 'diretório' de qualquer maneira - antes das 9x). Por favor, pare de dizer 'pasta'. Quanto ao seu último comando, você nem precisa do '/' apenas para sua informação.
Pryftan

15

Espero que isso seja útil ...

Expandir grepum 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:

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 de qual é o tipo de arquivo, pode restringir sua pesquisa especificando extensões de tipo de arquivo a serem pesquisadas, nesse caso .pasOU .dfmarquivos:

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. .no findespecifica no diretório atual.
  2. -name" *.*": Para todos os arquivos (-name " *.pas" -o -name " *.dfm"): Apenas os *.pasOU *.dfmarquivos ou especificado com-o
  3. -type f especifica que você está procurando arquivos
  4. -print0e --nulldo outro lado do |(canal) são os cruciais, passando o nome do arquivo do findpara o grepincorporado no xargs, 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.

-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').
Pryftan

15

Um Simple findpode ser útil. alias no seu ~/.bashrcarquivo:

alias ffind find / -type f | xargs grep

Inicie um novo terminal e faça o seguinte:

ffind 'text-to-find-here'

14

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 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 Python re . 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 pycontendo Pool(seguida por palavra Adaptor, faça 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 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.


14

Se você deseja usar estritamente find, use find + grep:

find /path/to/somewhere/ -type f -exec grep -nw 'textPattern' {} \;

passos:

1. Use findpara procurar arquivos,
2.Then executar grepem todos eles.

Isso pode dar a você o poder de findencontrar arquivos.

  • Use -name Patternse você quiser grepapenas determinados arquivos:

    find /path/to/somewhere/ -type f -name \*.cpp -exec grep -nw 'textPattern' {} \;

Você pode brincar com ele e usar diferentes opções findpara melhorar ou restringir sua pesquisa de arquivos.


Qual é a diferença? Funcionará com espaços no caminho do arquivo?
Peter Mortensen

13

Usar:

grep -c Your_Pattern *

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


13

grep é seu bom amigo para conseguir isso.

grep -r <text_fo_find> <directory>

Se você não se importa com o caso do texto a ser encontrado, use:

grep -ir <text_to_find> <directory>

No meu caso, parece que ele procura em todos os lugares, mesmo se eu fizer especificar o diretório
Patros

@Pathros Provavelmente, a recursão está ativada e qual diretório você especifica. Em outras palavras, a recursão muda as coisas dessa maneira.
Pryftan

@ Pathros Ah, e se houver algum -s na string de pesquisa, você deve passar --primeiro para o grep; isso pode causar efeitos colaterais interessantes de outra maneira!
Pryftan

13

Estou fascinado por como o grep é simples com 'rl':

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

-r to recursively find a file / directory inside directories..
-l to list files matching the 'pattern'

Use '-r' sem 'l' para ver os nomes dos arquivos seguidos pelo texto em que o padrão é encontrado !

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

Funciona perfeitamente ...


Isso também funciona no Git Bash (Windows).
Peter Mortensen

Mas isso implica que todos os arquivos devem ser pesquisados ​​(nenhum filtro no nome do arquivo ou no nível da extensão do arquivo, como .txt). Ou existe uma maneira de fazer isso?
Peter Mortensen

12

Para procurar a sequência e gerar apenas essa linha com a sequência 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;

1
Vejo apenas desvantagem em comparação ao uso find … -exec grep 'str' {} \;(se você precisar usá find-lo).
Phk # 7/16

1
Isso seria horrível se qualquer um dos arquivos encontrados por findespaços contidos ... você pudesse acabar com greppingos arquivos errados e / ou com a falta dos arquivos certos. Basta usar find ... -exec grep ...se você precisar usar find.. mas, neste caso, grep -r ...é suficiente.
shalomb

1
qual é o sentido de usar um loop sobre os resultados de find e grep? Isso fica desnecessariamente complicado.
fedorqui 'Então, pare de prejudicar'

12

Existe uma ackferramenta que faria exatamente o que você está procurando.

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

ack -i search_string folder_path/*

Você pode ignorar -ia pesquisa que diferencia maiúsculas de minúsculas


2
O que isso está adicionando às respostas existentes? Isso foi sugerido há mais de três anos atrás.
fedorqui 'Então pare de prejudicar'

1
@fedorqui 1) sem tubulação! 2) Use expressões regulares 3) Obtenha números de linhas, nome de arquivo com caminho relativo, texto destacado etc. útil para editar após a pesquisa, por exemplo, "vim + lineno path / file.cpp" você acertará na linha sem interesse. Veja a saída do comando "ack include \ | hpp" que pesquisa as palavras-chave "include" ou "hpp" em minha pasta de pesquisa e subpastas. Espero que o ponto esteja claro. Aqui está o exemplo de saída (Não é possível mostrar os destaques das palavras-chave com texto simples) process / child.hpp 11: boost / process / child.hpp process / all.hpp 21: #include <boost / process / execute.hpp>
Pal

12

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.


ranger seria na mesma ideia
nilon

11

O comando abaixo funcionará bem para esta abordagem:

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

2
qual é o sentido de usar finde então grep -r? Eles são feitos para o mesmo, então isso é redundante.
fedorqui 'Então pare de prejudicar'

ohh !! corrigida, realmente encontrar é para executar grep em arquivos filtrados e não todos, graças
Pradeep Goswami

2
Ainda assim, isso não faz sentido, você pode filtrar com find.
fedorqui 'SO pare de prejudicar'

11

Evite o aborrecimento 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"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.