我试图找到包含 Java 类的 JAR。 JAR 为 zip 格式。
我的第一次尝试是:
$ 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
我找到了该类,但我仍然不知道 25 个匹配文件中的哪一个包含它(有两个 JAR 包含它)。所以我想到用tee
中间来输出文件名。
$ 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
我本来希望看到一个文件名,后面跟着 Controller.class(用于匹配文件)和下一个文件名(用于非数学)。然而,现在我想了一下,标准输出只是在管道中流动并由 xargs 处理,所以这是有道理的。
我可以使用标准错误,但是我想,由于进程是同时运行的,我可能会遇到计时问题,导致输出不符合我希望看到的顺序。
所以必须有更好的方法来解决这个问题,有人有想法吗?
更新:在等待答案时,我写了一个可怕的 Perl one liner,它可以解决问题,但期待看到更优雅的解决方案。
$ find -name "*3.0.6.RELEASE.jar" | perl -e 'while (<>) { \
$file=$_; @class=`unzip -l $_`; foreach (@class) { \
if (/stereotype.Controller/) {print "$file $_";} } }'
输出:
./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
答案1
尝试这个:
find -name "*3.0.6.RELEASE.jar" -exec sh -c 'unzip -l "{}" | grep -q stereotype.Controller' \; -print
这里不需要 forxargs
或for
循环。所有这些都可以通过一个find
.如果您还想输出 grep 的内容,只需删除-q
-grep
但请注意grep
匹配项将会出现前每个文件名。为了获得更清晰的输出,您可以-exec echo \;
在最后添加。
答案2
在你的第一个一行中,在grep
命令中添加-H
选项。也就是在结果中包含文件名。
这是来自手册页 -
-H, --with-filename
Print the filename for each match.</strike>
更新
也许这个脚本会有所帮助 -
#!/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
单线:
for i in `find . -name "*.jar"`; do jar tvf $i | grep "search pattern" && echo $i ; done
唯一遗憾的是jar文件的名称会显示在grep
内容之后
答案3
一个旧线程,但这看起来是完成此任务的更干净的方法: 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]*