grep tous les fichiers .java dans un répertoire pour une chaîne particulière

12

Comment rechercher dans tous les fichiers .java une simple chaîne (pas une expression régulière) dans le répertoire actuel et tous les sous-répertoires sous Mac OS X? Je veux juste imprimer une liste de noms de fichiers et de répertoires qui correspondent.

John Topley
la source
Merci d'avoir posé cette question, donc je n'ai pas à le faire. Maintenant, je dois juste comprendre comment exclure ".git" et j'ai terminé un peu.
Dan Rosenstark
Je pense que la réponse de js est plus concise, ça craint quand même de taper - y compris, mais quand même. Pourrait probablement écrire un alias pour cacher cela
Craig Tataryn

Réponses:

19

Et le toujours populaire

find . -name '*.java' | xargs grep -l 'string'

EDIT (par Frank Szczerba):

Si vous avez affaire à des noms de fichiers ou à des répertoires contenant des espaces, la façon la plus sûre de procéder est:

find . -name '*.java' -print0 | xargs -0 grep -l 'string'

Il y a toujours plus d'une façon de le faire.

David Mackintosh
la source
11

La réponse UNIX traditionnelle serait celle qui a été acceptée pour cette question:

find . -name '*.java' | xargs grep -l 'string'

Cela fonctionnera probablement pour les fichiers Java, mais les espaces dans les noms de fichiers sont beaucoup plus courants sur Mac que dans le monde UNIX traditionnel. Lorsque les noms de fichiers avec des espaces sont transmis via le pipeline ci-dessus, xargs interprète les mots individuels comme des noms différents.

Ce que vous voulez vraiment, c'est de séparer les noms pour rendre les limites sans ambiguïté:

find . -name '*.java' -print0 | xargs -0 grep -l 'string'

L'alternative consiste à laisser find exécuter grep pour vous, comme le suggère Mark, bien que cette approche soit plus lente si vous recherchez un grand nombre de fichiers (car grep est invoqué une fois par fichier plutôt qu'une fois avec la liste complète des fichiers).

Frank Szczerba
la source
Vous pouvez également utiliser l'option "--replace" dans xargs pour gérer les noms de fichiers contenant des espaces: ... | xargs --replace grep 'string' '{}' ({} serait remplacé par le nom de fichier)
arathorn
1
Les versions modernes de find (y compris celle installée sur OS X) prennent en charge "-exec <command> {} +" où le signe plus à la fin (au lieu de \;) indique à find de remplacer {} par "autant de chemins que possible ... Ceci est similaire à celui de xargs (1) "(à partir de la page de manuel).
Doug Harris
7

Utilisez le grep qui est meilleur que grep, ack :

ack -l --java  "string" 
bortzmeyer
la source
3
ack n'est pas installé sur Mac OS X par défaut.
John Topley
Je ne sais pas ce que signifie "par défaut". Sur de nombreux systèmes d'exploitation, vous choisissez ce que vous installez, il est donc difficile de trouver des programmes qui sont toujours présents. À la fois, un compilateur C était toujours là et Perl était rare ...
bortzmeyer
1
Cela signifie qu'il fait partie de l'installation standard du système d'exploitation. J'ai les outils de développement installés sur mon Mac et ils n'installent pas ack. Vous devez l'installer vous-même. Si vous l'avez, c'est une belle syntaxe.
John Topley
Dans le cas d'ack, il s'agit d'un seul programme Perl sans dépendances de module. Si vous pouvez "installer" des programmes dans votre répertoire ~ / bin, vous pouvez tout aussi bien "installer" ack.
Andy Lester
4

Cela utilisera en fait une expression régulière si vous le souhaitez, restez simplement à l'écart des métacaractères, ou échappez-les, et vous pouvez rechercher des chaînes.

find . -iname "*.java" -exec egrep -il "search string" {} \;

Mark Thalman
la source
3
grep -rl --include="*.java" simplestring *
js.
la source
1
Cela semble être la meilleure réponse ici - si grep fait tout, pourquoi utiliser find & xargs?
Peter Gibson
Pour info, étant donné ce qui est demandé dans la question, ce devrait être un petit "l" et non un grand "L" dans cette commande
Craig Tataryn
Craig a raison, j'ai corrigé ma réponse.
js.
1

Puisqu'il s'agit d'une question OSX, voici une réponse plus spécifique à OSX.

Sautez findet utilisez à Spotlightpartir de la ligne de commande. Beaucoup plus puissant!

COMMAND LINE SPOTLIGHT - FIND MEETS GREP

La plupart des gens ne savent pas que vous pouvez effectuer des recherches Spotlight à partir de la ligne de commande. Pourquoi se souvenir de toutes les options de recherche et de grep des arcanes et que pas quand vous pouvez laisser Spotlight faire le travail pour vous. L'interface de ligne de commande de Spotlight s'appelle mdfind. Il a tout le même pouvoir que la recherche GUI Spotlight et plus encore car il est scriptable sur la ligne de commande!


la source
0

Essayez ceci:

grep -rl "string" */*java
dwj
la source
1
Cela donne "grep: * / * java: aucun fichier ou répertoire" sur Mac OS X.
John Topley
Le problème ici est qu'il ne trouvera que les fichiers * .java d'un niveau. Voir la réponse de Mark Thalman pour IMHO la bonne façon de le faire.
Ludwig Weinzierl
Désolé, pas sur mon Mac. La version Mac de grep n'a-t-elle pas l'indicateur -r (récursif)?
dwj
C'est le cas, mais c'est la sortie que j'ai obtenue lors de la recherche d'une chaîne dont je sais qu'elle se trouve dans les fichiers.
John Topley
0

Vous pouvez également utiliser un programme GUI comme TextWrangler pour faire une recherche plus intuitive où les options sont dans l'interface.

Mark Thalman
la source
0
grep "(your string)" -rl $(find ./ -name "*.java")

Si vous souhaitez ignorer la casse, remplacez -rl par -irl. (votre chaîne) peut également être une expression régulière si vous en voyez le besoin.

rire_homme
la source