Vous cherchez une class Java dans un set de files JAR avec find, unzip, grep

J'essayais de find le JAR contenant une class Java. Les files JAR sont au format zip.

Ma première tentative était:

$ find -name "*3.0.6.RELEASE.jar" | xargs -l1 unzip -l \ | grep stereotype.Controller 554 2011-08-18 16:49 org/springframework/stereotype/Controller.class 554 2011-08-18 16:49 org/springframework/stereotype/Controller.class 

J'ai trouvé la class, mais je ne sais toujours pas laquelle des 25 files correspondants la contient (il y en a deux JARs la contenant). J'ai donc pensé à utiliser tee au milieu pour sortir les noms de files.

 $ find -name "*3.0.6.RELEASE.jar" | tee - | xargs -l1 unzip -l \ | grep stereotype.Controller 554 2011-08-18 16:49 org/springframework/stereotype/Controller.class 554 2011-08-18 16:49 org/springframework/stereotype/Controller.class 554 2011-08-18 16:49 org/springframework/stereotype/Controller.class 554 2011-08-18 16:49 org/springframework/stereotype/Controller.class 

Je m'attendais à voir un nom de file suivi de la class Controller.class pour les files correspondants et par le nom de file suivant pour non mathing. Cependant, maintenant que j'y pense, la sortie standard coule juste dans le tuyau et est traitée par xargs, donc c'est logique.

Je pourrais utiliser l'erreur standard, mais je suppose que, puisque les process sont exécutés simultanément, je pourrais avoir des problèmes de timing qui rendent la sortie non dans l'ordre que j'espère voir.

Donc, il doit y avoir une meilleure façon d'aborder ce problème, quelqu'un a des idées?

MISE À JOUR : En attendant une réponse, j'ai écrit un liner Perl horrible qui fait l'affaire, mais j'ai hâte de voir des solutions plus élégantes.

 $ find -name "*3.0.6.RELEASE.jar" | perl -e 'while (<>) { \ $file=$_; @class=`unzip -l $_`; foreach (@class) { \ if (/stereotype.Controller/) {print "$file $_";} } }' 

Sortie:

 ./spring-context/3.0.6.RELEASE/spring-context-3.0.6.RELEASE.jar 554 2011-08-18 16:49 org/springframework/stereotype/Controller.class ./org.springframework.context/3.0.6.RELEASE/org.springframework.context-3.0.6.RELEASE.jar 554 2011-08-18 16:49 org/springframework/stereotype/Controller.class 

Essaye ça:

 find -name "*3.0.6.RELEASE.jar" -exec sh -c 'unzip -l "{}" | grep -q stereotype.Controller' \; -print 

Il n'y a pas besoin de xargs ou d'une boucle for ici. Tout peut être fait avec une seule find . Si vous voulez également afficher le contenu qui a été grepped, supprimez simplement l'option -q de grep – mais notez que les correspondances grep apparaîtront avant chaque nom de file. Pour une sortie plus claire, vous pouvez append -exec echo \; à la fin.

Dans votre premier one-liner, dans la command grep ajoutez l'option -H . C'est d'inclure le nom de file dans le résultat.

Voici de la man-page –

 -H, --with-filename Print the filename for each match.</ssortingke> 

METTRE À JOUR

Peut-être que ce script va aider –

 #!/bin/bash searchSTR="YOUR SEARCH" for i in `find . -name "*jar"` do echo "Scanning $i ..." jar tvf $i | grep $searchSTR > /dev/null if [ $? == 0 ] then echo "==> Found \"$searchSTR\" in $i" fi done 

Bon mot:

 for i in `find . -name "*.jar"`; do jar tvf $i | grep "search pattern" && echo $i ; done 

La seule partie sortingste est le nom du file jar sera affiché après le contenu grep

Un vieux fil mais cela ressemble à un moyen plus propre de faire cela: http://alumnus.caltech.edu/~leif/opensource/cpcheck/CpCheckApp.html

 Windows: cpcheck [flags] classpath [classpath]* Unix: ./cpcheck.sh [flags] classpath [classpath]* Java: java -jar cpcheck.jar [flags] classpath [classpath]*