Como pesquiso uma string em um arquivo PHP usando `grep`?


11

Estou procurando uma declaração de classe em um site com centenas de arquivos PHP. Como posso fazer isso na pasta atual e nas subpastas usando grep ?

Eu testei cding para a pasta e, em seguida, algo como

grep -r 'class MyClass' *.php

Quando isso migra para o superusuário, você pode querer dizer algo sobre o que você queria que grep -rnão deu a você.

Estou confuso - você não respondeu a si mesmo? quais foram os resultados dessa linha? você está tentando otimizá-lo ainda mais? imagine ler esta pergunta como outra pessoa, porque é confusa e incerta.
você precisa saber é o seguinte

comentários @other: Sua declaração grep -r não está dando o que ele quer, a menos que todas as pastas terminar com .php que provavelmente não é o caso ...
David Oneill

Eu não recebi nada. Presumo que não funcionou porque eu sei que ele encontra quando im na pasta que tem o arquivo com esta classe

Encontrei o arquivo por sorte. Ao procurar o arquivo na pasta que possui o arquivo PHP com essa linha, ele o encontra (não há necessidade de -r). Se eu CD para a raiz e faço a pesquisa com recursão -r, não retorna nada.

Respostas:


24

Podes tentar

grep -r --include=*.php "search string" /path/to/dir

1
Funciona bem. Eu continuo esquecendo, mas felizmente sempre há essa resposta novamente para me ajudar. :)
GolezTrol

@GolezTrol Fico feliz em saber que :-)
rahul286

9

Eu recomendo que você use algo como ctags em vez de fazê-lo com um grep. No entanto, se você quiser, pode fazer algo como

 find <top level dir> -name \*.php | xargs grep "class MyClass"

Obviamente, isso pressupõe que você tenha apenas um espaço entre eles classe o myClassque pode não ser verdade. É fácil alterar o regexp para procurar qualquer número de espaços em branco.


4

Se você usar -r, provavelmente desejará pesquisar recursivamente apenas o diretório atual :

grep -r 'class MyClass' .

Observe o período no final do acima.

O que você disse grepfoi que queria que ele pesquisasse recursivamente todos os *.phparquivos ou diretórios , mas provavelmente não tinha nenhum diretório que terminasse em uma extensão .php. A descrição acima é a maneira mais simples possível de fazer a pesquisa, mas também inclui arquivos de outros tipos, o que é especialmente problemático quando você tem diretórios .svn em todos os lugares. Se você não possui muitos outros tipos de arquivo, o acima é geralmente suficiente e funciona bem.

A maioria das encarnações do grep não tem como especificar extensões de arquivo que podem ser pesquisadas; portanto, você geralmente usa o find em conjunto com ele:

find <startDir> -iname '*.php' -exec grep 'class[ \t]*MyClass' {} \;

-inamediz a algumas versões do grep que você deseja fazer uma pesquisa de nome de arquivo sem distinção entre maiúsculas e minúsculas, mas muitas das variantes não encontradas no GNU de find não suportam, então você pode usá-lo -name.

A -execopção acima tem o efeito colateral de chamar grep para cada arquivo, o que é bastante caro.

Ainda outras versões do grep suportam um +que diz ao find para anexar os argumentos juntos para reduzir o número de invocações do executável:

find <startDir> -iname '*.php' -exec grep 'class[ \t]*MyClass' {} + \;

Uma maneira frequentemente recomendada de reduzir chamadas é usar xargs que dispararão o grep o menor número de vezes possível, mas quantas vezes for necessário:

find <startDir> -iname \*.php | xargs grep "class[ \t]*MyClass"

xargsé inteligente o suficiente para transmitir grep até o número máximo de argumentos suportados na linha de comando, mas a variação acima não lida com certos caracteres como espaços muito bem. Por exemplo, se 'the file.php', um nome de arquivo grep receberia 'the' como argumento e 'file.php' como argumento para que ambos não fossem encontrados. Em vez disso, usamos:

find <startDir> -iname \*.php -print0 | xargs -0 grep "class[ \t]*MyClass"

print0e -0trabalhem juntos e usem argumentos seguidos por um caractere nulo para que o argumento seja identificado de maneira completa e inequívoca.

Se você tiver mais de um espaço depois classou uma guia, poderá permitir mais caracteres alterando a expressão regular:class[ \t]*MyClass

Esta postagem no StackOverflow tem outros exemplos e demonstra como excluir determinados diretórios, como os diretórios .svn.


Isso pesquisa todos os arquivos. Também arquivos que não são arquivos .php.
GolezTrol 5/05

Atualizei a postagem para incluir muitos outros exemplos.
Kaleb Pederson


1
grep -r 'class MyClass' *.php

procurará em todas as pastas com nomes terminados em .php

grep -r 'class MyClass' . | grep .php

procurará a classe MyClass em todos os arquivos em todas as subpastas e retornará apenas os que tiverem .php.


1

find . -type f -name *.php -print -exec grep \"class MyClass\" {} \; fornecerá o conteúdo da linha encontrada, bem como o caminho para o arquivo.


1

Caso os arquivos correspondentes possam ter nomes arbitrários, considere usar -print0

encontrar . -type f -name '* .php' -print0 | xargs -0 grep 'classe MyClass'


1
grep -rl 'class MyClass' . --include \*.php

l mostra apenas o nome do arquivo

r é recorrente

. pesquisas na pasta atual

--include limits extensão do nome de arquivo


1

Provavelmente você deseja insensibilidade a maiúsculas e minúsculas, e o grep será encerrado se não encontrar nenhuma instância do padrão de arquivo desejado no diretório atual. Ele precisa saber por onde começar, por assim dizer, e nenhum arquivo correspondente não produz um caminho inicial.

Se houver pelo menos um arquivo da extensão desejada, você poderá usar o egrep -ir. finde xargsmostre seu poder com diretórios simples (mas muito grandes) em que o grep falha e qualificadores extras (por exemplo, se você deseja procurar apenas arquivos .inc, .php e php3). Mas perde bastante conveniência e velocidade na minha experiência. Para declarações humanas de classe escrita, um grande problema será o espaço em branco. Então use egrep em vez de grep. Também LC_ALL = C para velocidade extra. Por conveniência, costumo usar:

LC_ALL=C egrep -irn "class[ ]*myclass([ ]|\n)" * | egrep "\.(inc|php[35]?)"

-i -- case insensitive
-r -- recursive for all file pattern (here *)
-n -- include the line number
LC_ALL=C -- search in ASCII, not in utf8, this is much faster.

[ ]* -- match any number of spaces before the class name
([ ]|\n) -- match a space or newline after the classname

Isso ainda pode corresponder a comentários, como // class myclass exists in file, mas acho que eles são pequenos relativamente e podem ser filtrados com... | fgrep -v '//'

Você também pode incluir máscaras de arquivo mais complexas (por exemplo, para capturar a maioria dos arquivos .inc e .php) no padrão do arquivo egrep, da seguinte maneira:

egrep "pattern" *.[ip]*

Isso (com as primeiras opções) será bastante rápido e limitado principalmente aos arquivos php.

HTH


0

Eu sei que diz usando grep, mas o meu favorito é usar ack-grep:

ack-grep "class MyClass"

Isso é executado de forma recursiva, lista o nome do arquivo encontrado, com os números das linhas onde são encontrados e os destaques. Para direcionar especificamente arquivos php, você pode executar:

ack-grep --type-set php:ext:php "path"

O pacote tem uma infinidade de opções; Definitivamente, eu o recomendaria (e navegaria em sua página de manual associada) para fazer coisas sofisticadas.

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.