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

sti*_*vlo 7 command-line grep bash find 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
Run Code Online (Sandbox Code Playgroud)

我找到了这个类,但我仍然不知道 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
Run Code Online (Sandbox Code Playgroud)

我希望看到一个文件名,后跟用于匹配文件的 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 $_";} } }'
Run Code Online (Sandbox Code Playgroud)

输出:

./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
Run Code Online (Sandbox Code Playgroud)

roz*_*acz 9

尝试这个:

find -name "*3.0.6.RELEASE.jar" -exec sh -c 'unzip -l "{}" | grep -q stereotype.Controller' \; -print
Run Code Online (Sandbox Code Playgroud)

这里不需要 forxargsfor循环。所有这些都可以通过一个find. 如果您还想输出 grepped 的内容,只需删除-q选项grep- 但请注意grep匹配将出现每个文件名之前。为了更清晰的输出,您可以-exec echo \;在最后添加。