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]*