Como eu procuro uma string em um arquivo PHP usando 'grep'?

10

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

Testei cd ing para a pasta e, em seguida, algo como

grep -r 'class MyClass' *.php
    
por Peter Mortensen 19.01.2010 / 17:40

10 respostas

21

Você pode tentar

grep -r --include=*.php "search string" /path/to/dir
    
por 18.04.2013 / 12:07
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"

Isso, obviamente, pressupõe que você tenha apenas um espaço entre class e myClass , o que pode não ser verdade. É fácil alterar o regexp para procurar qualquer número de espaços em branco.

    
por 19.01.2010 / 17:44
4

Se você usa -r , provavelmente deseja pesquisar recursivamente apenas o diretório atual :

grep -r 'class MyClass' .

Observe o período no final do acima.

O que você disse a grep foi que você queria que ele pesquisasse recursivamente cada *.php arquivo ou diretório , mas provavelmente você não tinha diretórios que tivessem terminado em uma extensão .php. A descrição acima é a maneira mais simples 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 tem muitos outros tipos de arquivos, o acima é geralmente suficiente e funciona bem.

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

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

-iname diz 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 do GNU não o suportam, então você pode usar -name .

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

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

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

Uma maneira freqüentemente recomendada para reduzir invocações é usar xargs que dispararão o grep o menor número de vezes possível, mas quantas vezes forem necessárias:

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

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

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

print0 e -0 trabalham juntos e usam argumentos seguidos por um caractere nulo para que o argumento seja completamente e sem ambigüidade identificado.

Se você tiver mais de um espaço após class ou uma guia, convém permitir mais caracteres alterando a regex: class[ \t]*MyClass

Este post em O StackOverflow tem outros exemplos e demonstra como excluir determinados diretórios, como diretórios .svn.

    
por 19.01.2010 / 17:43
3

Usando a sempre maravilhosa ack ,

ack --php 'class MyClass'
    
por 19.01.2010 / 18:17
1
grep -r 'class MyClass' *.php

pesquisará todas as pastas cujos nomes terminem em .php

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

irá procurar pela classe MyClass em todos os arquivos em todas as subpastas, então só retornará aqueles que possuem .php neles.

    
por 19.01.2010 / 17:44
1

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

    
por 19.01.2010 / 17:45
1

Caso os arquivos correspondentes possam ter nomes arbitrários, você deve considerar o uso de -print0

find . -type f -name '*.php' -print0 | xargs -0 grep 'class MyClass'

    
por 09.04.2013 / 13:07
1
grep -rl 'class MyClass' . --include \*.php

l mostra apenas o nome do arquivo

r é recursivo

procura na pasta atual

- inclui limites de extensão de nome de arquivo

    
por 04.03.2016 / 17:59
1

Provavelmente você quer tolerância a insensibilidade a maiúsculas e minúsculas e espaço em branco, e o grep terminará 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 produz nenhum caminho inicial.

Se houver pelo menos um arquivo da extensão desejada, você poderá usar egrep -ir. find e xargs mostram seu poder com diretórios simples (mas muito grandes) que o grep falha e qualificadores extras (por exemplo, se você deseja procurar apenas por arquivos .inc, .php e php3). Mas perde um pouco de conveniência e velocidade na minha experiência. Para declarações de classes escritas por humanos, um grande problema será o espaço em branco. Então use o egrep ao invés do 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 relativamente pequenos 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 forma:

egrep "pattern" *.[ip]*

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

HTH

    
por 26.07.2016 / 08:27
0

Eu sei que usa grep , mas meu favorito é usar ack-grep :

ack-grep "class MyClass"

Isso é executado recursivamente, lista o nome do arquivo em que encontra resultados, com números de linha para onde eles são encontrados e 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; Eu definitivamente recomendo (e navega em sua página de manual associada) por fazer coisas extravagantes.

    
por 04.03.2016 / 19:28

Tags