Procurando vários arquivos por uma string no LInux

5

Como pesquiso arquivos, alguns dos quais podem ser diretórios (neste caso recursivamente) para uma determinada string?

Gostaria de pesquisar os arquivos de origem para uma definição de classe, por isso também seria ótimo se houvesse o nome do arquivo que o contém antes de cada string de saída.

    
por Alex 29.06.2009 / 12:05

9 respostas

8

Você pode usar o grep:

grep -rn 'classname' /path/to/source

Isso também imprimirá o número da linha ao lado de cada partida.

Caso insensitivo:

grep -rin 'classname' /path/to/source

Pesquise de forma não recursiva em todos os arquivos cpp:

grep -n 'classname' /path/to/source/*.cpp
    
por 29.06.2009 / 12:08
4

Todas as respostas acima funcionarão perfeitamente, mas podem causar falsos positivos se você tiver a string em mais do que apenas o código-fonte. Digamos que você esteja procurando onde você usa a classe FooBar em um projeto java, você pode procurar por todos os arquivos chamados * .java e grep.

# grep "FooBar" -Hn $(find -name "*.java")

A seção entre o $ () será expandida para a saída desse comando. O -H imprime o nome do arquivo. É o padrão onde há mais de um nome de arquivo, mas explicitamente o adicionamos aqui caso a expansão retorne apenas um nome de arquivo. O -n imprime o número da linha da partida.

Isso funcionará para projetos pequenos, mas se você estiver lidando com um projeto maior, haverá a possibilidade de a descoberta se expandir para uma cadeia maior do que o limite da linha de comando. Por isso, é mais seguro usar:

# find -name "*.java" -print0 | xargs -0 grep "FooBar" -Hn 

O xargs recebe a entrada do padrão e a divide para que ela caiba na linha de comando, executando o comando várias vezes, se necessário. Os -print0 e -0 são necessários para lidar com arquivos com espaços em seus nomes.

Você também pode procurar todos os nomes de arquivos com uma correspondência:

# find -name "*.java" -print0 | xargs -0 grep "FooBar" -l

O -l exibirá apenas o nome do arquivo e parará de procurar em um determinado arquivo assim que encontrar uma correspondência.

Se você estiver fazendo esse tipo de coisa com frequência, convém examinar uma ferramenta como ctags ou tags exuberantes, que mantêm um índice de pesquisa do seu código-fonte e podem responder a esse tipo de pergunta rapidamente. Tanto o vim quanto o emacs têm suporte para essas ferramentas. Você também pode gostar de ver uma IDE como eclipse, que pode fazer referência cruzada muito bem.

(Eu sei que você estava procurando por uma definição de classe, mas em Java uma classe será definida em um arquivo com o mesmo nome da classe. Se você estivesse fazendo cpp, você poderia fazer algo como:

# find -name "*.cpp" -o -name "*.cc" -o -name "*.h" -o -name "*.hpp" -print0 | \
  xargs -0 egrep "class\s+FooBar" -Hn 
    
por 29.06.2009 / 13:17
2

Para pesquisar pelo código-fonte, descobri que o ACK (melhor que o grep) é melhor do que o marketing ( betterthangrep.com ) para citar o marketing. Sua saída é mais fácil de ler e vai fazer muitas coisas automagicamente, como ignorar arquivos de código não-fonte: diretórios VCS (por exemplo, CVS e .svn), arquivos de backup.

    
por 29.06.2009 / 12:26
2

ack é melhor para pesquisar códigos-fonte, pois ele já reconhece algumas das extensões de arquivo mais populares (c, perl, etc). É tão rápido quanto o grep e, por padrão, ignora todo o artefato de controle de versão. Por exemplo, se você quiser pesquisar algum código-fonte perl padrão, você pode usar

ack --perl pattern

em vez de

grep pattern $(find . -name '*.pl' -or -name '*.pm' -or -name '*.pod' | grep -v .svn)
    
por 02.07.2009 / 06:07
0
grep -r string *

localiza todos os arquivos contendo os caracteres "string" em todos os arquivos (não ocultos) no diretório atual e em todos os subdiretórios de forma recursiva. Você pode usar os regexes usuais para ajustar a string. Veja as páginas info / man do grep para mais opções.

    
por 29.06.2009 / 12:12
0

Já respondi (acho que é isso que você está procurando) nesta postagem de falha de servidor:

Pesquisa de texto recursivo com padrões de grep e file

    
por 29.06.2009 / 13:21
0

isso é algo que eu me encontro usando muito, então eu coloquei duas funções bash no meu .bashrc
Primeiro, faz uma busca recursiva por texto em nomes de arquivos.
O segundo fará uma busca recursiva por texto dentro dos arquivos que retornam os nomes dos arquivos correspondentes.

ff () {
        find . -name "*$@*" -print; 
}


fff () {
    find . -type f -print0 | xargs -0 grep -l $@
}

uso de exemplo:

[lunix@godzilla ~/tmp]$ ff foo
./slideshow/foo
./slideshow/velocity_puppet_workshop_2009/repo/modules/foo

[lunix@godzilla ~/tmp/test]$ fff  commodo
./file2
[lunix@godzilla ~/tmp/test]$ ll
total 16K
drwxr-xr-x 2 lunix lunix 4.0K 2009-06-29 23:01 .
drwxr-xr-x 4 lunix lunix 4.0K 2009-06-29 22:57 ..
-rw-r--r-- 1 lunix lunix 1.3K 2009-06-29 22:59 file1
-rw-r--r-- 1 lunix lunix 1.7K 2009-06-29 23:00 file2
    
por 29.06.2009 / 15:00
0

Este clássico find + exec também pode ser útil:

find /path/to/ -type f -exec grep -i 'string' {} \;
    
por 23.09.2010 / 21:16
-1

grep -rn * funcionará !!

    
por 29.06.2009 / 12:18

Tags