使用 find、unzip、grep 在一组 JAR 中查找 Java 类

使用 find、unzip、grep 在一组 JAR 中查找 Java 类

我试图找到包含 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

这里不需要 forxargsfor循环。所有这些都可以通过一个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]*

相关内容