Como faço para encontrar texto em um arquivo e fazer com que ele pesquise em várias subpastas?

7

Estou procurando um nome de função e a estrutura da pasta é profunda e há muitos arquivos para serem visualizados.

Geralmente eu uso algo como find * | grep functionname , mas essa é a melhor maneira?

    
por tooshel 12.03.2011 / 02:40

7 respostas

15

$ find . -type f -print0 | xargs -0 grep foo
$ grep -r foo . # GNU grep only

e em zsh com setopt extendedglob ,

$ grep foo **/*(.)
    
por 12.03.2011 / 02:51
5

Há também ack , que é projetado especificamente para esse tipo de tarefa e faz a pesquisa de subpastas automaticamente.

    
por 12.03.2011 / 07:44
2

Como uma alternativa às respostas find | xargs , você pode considerar o uso de ctags , já que você diz que não está pesquisando texto, mas especificamente para nomes de função.

Para isso, execute ctags em sua origem para criar um arquivo TAGS e, em seguida, execute seu grep no arquivo TAGS , que irá gerar linhas no seguinte formato:

{tagname}<Tab>{tagfile}<Tab>{tagaddress}

Em que tagname conterá o nome da função, tagfile é o arquivo em que está e tagaddress será um comando vi para chegar a essa linha. (Pode ser apenas um número de linha.)

(Existe uma maneira fácil de fazer algo semelhante com os vários índices que o eclipse constrói, ou apenas consultar o banco de dados do eclipse?)

    
por 12.03.2011 / 12:16
1

o que há de errado com grep -r (== grep --recursive )? Estou faltando alguma coisa aqui?

(+ 1 para ack também - eu uso regularmente ambos)

edit: Encontrei um excelente artigo detalhando as possibilidades e armadilhas se você não tem GNU grep aqui . Mas, sério, se você não tem GNU grep disponível, obter ack é ainda mais altamente recomendado.

    
por 12.03.2011 / 11:14
0

find . | xargs grep falhará em nomes de arquivos com espaços:

> echo test > "a b c"
> find . | xargs grep test
grep: ./a: No such file or directory
grep: b: No such file or directory
grep: c: No such file or directory

Observe que até mesmo -print0 tem esse problema.

É melhor, na minha opinião, usar -exec grep com find, que lidará com todos os nomes de arquivos internamente e evitará esse problema:

> find . -exec grep test {} \;
test
>
    
por 12.03.2011 / 16:55
0

Se seus discos são rápidos, você pode querer paralelizar o grep:

find . -type f -print0 | parallel -0 grep foo

Assista ao vídeo de introdução para saber mais sobre o GNU Parallel: link

    
por 16.03.2011 / 15:10
0

$ find -type f -print0 | xargs -r0 grep foo

-r in xargs evita a execução do comando se não houver entrada. É uma extensão do GNU.

Há também ag que é especificamente projetado para isso e é melhor que ack . Está disponível em versões recentes do Debian / Ubuntu no pacote silversearcher-ag .

    
por 12.03.2011 / 06:39