Je recherche une déclaration de classe sur un site avec des centaines de fichiers PHP. Comment puis-je faire cela dans le dossier et les sous-dossiers actuels à l'aide de grep ?
J'ai testé cd
dans le dossier puis quelque chose comme
grep -r 'class MyClass' *.php
grep -r
ne vous a pas donné.Réponses:
Tu peux essayer
la source
Je vous recommande d'utiliser quelque chose comme ctags plutôt que de le faire avec un grep. Cependant, si vous le souhaitez, vous pouvez faire quelque chose comme
Cela suppose bien sûr que vous avez un seul espace entre
class
etmyClass
qui pourrait ne pas être vrai. Il est facile de changer l'expression rationnelle pour rechercher un certain nombre d'espaces blancs.la source
Si vous utilisez
-r
, vous souhaiterez probablement rechercher récursivement uniquement le répertoire courant :Notez la période à la fin de ce qui précède.
Ce que vous avez dit,
grep
c'est que vous vouliez qu'il recherche récursivement chaque*.php
fichier ou répertoire , mais vous n'aviez probablement aucun répertoire se terminant par une extension .php. Ce qui précède est le moyen le plus simple de faire la recherche, mais inclut également des fichiers d'autres types, ce qui est particulièrement problématique lorsque vous avez des répertoires .svn partout. Si vous n'avez pas beaucoup d'autres types de fichiers, ce qui précède est généralement suffisant et fonctionne bien.La plupart des incarnations de grep n'ont pas de moyen de spécifier les extensions de fichier qui peuvent être recherchées, vous utilisez donc généralement find conjointement avec lui:
-iname
indique à certaines versions de grep que vous souhaitez effectuer une recherche de nom de fichier insensible à la casse, mais que de nombreuses variantes non GNU de find ne le prennent pas en charge, vous pouvez donc l'utiliser à la-name
place.L'
-exec
option ci-dessus a pour effet secondaire d'invoquer grep pour chaque fichier, ce qui est assez coûteux.D'autres versions de grep prennent en charge un
+
qui indique à find d'ajouter les arguments ensemble pour réduire le nombre d'appels de l'exécutable:Un moyen fréquemment recommandé de réduire les invocations consiste à utiliser des xargs qui déclencheront grep aussi peu de fois que possible mais autant de fois que nécessaire:
xargs
est assez intelligent pour passer grep jusqu'au nombre maximum d'arguments pris en charge sur la ligne de commande, mais la variation ci-dessus ne gère pas très bien certains caractères comme les espaces. Par exemple, si «le fichier.php» un grep de nom de fichier recevrait «le» en tant qu'argument et «fichier.php» en tant qu'argument afin que les deux ne soient pas trouvés. Au lieu de cela, nous utilisons:print0
et-0
travailler ensemble et utiliser des arguments suivis d'un caractère nul pour que l'argument soit complètement et sans ambiguïté identifié.Si vous avez plus d'un espace après
class
, ou un onglet, vous voudrez peut-être autoriser plus de caractères en changeant l'expression régulière:class[ \t]*MyClass
Ce message sur StackOverflow contient d'autres exemples et montre comment exclure certains répertoires, comme les répertoires .svn.
la source
En utilisant l' ack toujours merveilleux ,
la source
va rechercher dans tous les dossiers dont le nom se termine par .php
recherchera la classe MyClass dans tous les fichiers de tous les sous-dossiers, puis ne renverra que ceux qui contiennent .php.
la source
find . -type f -name *.php -print -exec grep \"class MyClass\" {} \;
vous donnera le contenu de la ligne sur laquelle il se trouve ainsi que le chemin d'accès au fichier.la source
Dans le cas où les fichiers correspondants pourraient avoir des noms arbitraires, vous devriez envisager d'utiliser
-print0
la source
l affiche uniquement le nom de fichier
r est récursif
. recherche dans le dossier actuel
--include limite l'extension du nom de fichier
la source
Vous voulez probablement une insensibilité à la casse et une tolérance aux espaces, et grep se terminera s'il ne trouve aucune instance du modèle de fichier souhaité dans le répertoire courant. Il doit savoir par où commencer, pour ainsi dire, et aucun fichier correspondant ne produit aucun chemin de démarrage.
S'il existe au moins un fichier de l'extension souhaitée, vous pouvez utiliser egrep -ir.
find
etxargs
montrer leur puissance avec des répertoires simples (mais très gros) sur lesquels grep échoue et des qualificatifs supplémentaires (par exemple si vous souhaitez rechercher des fichiers .inc, .php et php3 uniquement). Mais il perd un peu de commodité et de vitesse dans mon expérience. Pour les déclarations de classe écrites par l'homme, un gros problème sera les espaces blancs. Utilisez donc egrep au lieu de grep. Aussi LC_ALL = C pour une vitesse supplémentaire. Pour plus de commodité, j'utilise souvent:LC_ALL=C egrep -irn "class[ ]*myclass([ ]|\n)" * | egrep "\.(inc|php[35]?)"
Cela peut toujours correspondre à des commentaires, tels que
// class myclass exists in file
, mais je trouve qu'ils sont relativement petits, et ils peuvent être filtrés avec... | fgrep -v '//'
Vous pouvez également inclure des masques de fichiers plus complexes (par exemple, pour intercepter la plupart des fichiers .inc et .php) sur le modèle de fichier egrep comme ceci:
egrep "pattern" *.[ip]*
Cela (avec les premières options) sera assez rapide et principalement limité aux fichiers php.
HTH
la source
Je sais que cela dit d'utiliser
grep
, mais mon préféré est d'utiliserack-grep
:Cela s'exécute récursivement, répertorie le nom du fichier dans lequel il trouve les résultats, avec les numéros de ligne pour leur emplacement et les met en surbrillance. Pour cibler spécifiquement les fichiers php, vous pouvez exécuter:
Le paquet a une pléthore d'options; Je le recommanderais certainement (et parcourant sa page de manuel associée) pour faire des choses fantaisistes.
la source