如何在 JAR 文件中搜索字符串

我的应用程序是基于 JavaEE 构建的。

我这份申请里大约有50个罐子。

是否可以搜索一个特定的关键字(实际上我想搜索一个关键字 BEGIN REQUEST) ?

115111 次浏览

你可以在 Linux 或 OSX 上使用 zipgrep:

zipgrep "BEGIN REQUEST" file.jar

如果您希望搜索一些罐子,请执行

find libdir -name "*.jar" -exec zipgrep "BEGIN REQUEST" '{}' \;

其中 libdir是一个包含所有 jar 的目录。

对于 windows,您可以下载 cygwin 并在其下安装 zipgrep: http://www.cygwin.com/

编辑1

要查看找到表达式的文件的名称,

find libdir -name "*.jar" | xargs -I{} sh -c 'echo searching in "{}"; zipgrep "BEGIN REQUEST" {}'

编辑2

编辑1的简单版本

find libdir -name "*.jar" -print -exec zipgrep "BEGIN REQUEST" '{}' \;

下面的命令显示具有文件名和 jar 文件名的结果。

  1. 在 jar 文件列表中查找字符串。

    find <%PATH of the Folder where you need to search%> -name "*.jar" -print -exec zipgrep "jar$|<%STRING THAT YOU NEED TO FIND>" '{}' \;
    
  2. To find the class name in the list of jar file.

    find . -name "*.jar" -print -exec jar tvf {} \; |grep -E "jar$|<%CLASS NAME THAT YOU NEED TO FIND>\.class"
    

通过 WinRar 搜索,在 jar 内部搜索或者查找包含特定文本的类名是非常容易的。它的效率和总是为我工作,至少。

只要打开 WinRar 的任何一个罐子,点击”。."直到到达要开始搜索的顶部文件夹(包括子文件夹)。

确保检查以下选项:

1.)在“文件名查找”、“存档类型”等字段中提供“ *”

选中复选框“在子文件夹中查找”、“在文件中查找”、“在档案中查找”。

警告: 这不是一个准确的答案,它只是一个快速的启发式方法。如果您需要查找类的名称(例如,哪个 jar 有类 Foo?)或者是一个方法名,那么这个方法就可以工作了。

grep --text 'your string' your.jar

这将像搜索文本一样搜索 jar 文件。这样做更快,因为它不会扩展存档,但这也是为什么它不那么精确的原因。如果您需要详尽无遗,那么这不是您应该使用的方法,但是如果您想在取出 zipgrep之前尝试一些更快的方法,那么这是一个很好的方法。


来自 man grep,

  -a, --text
Process  a binary file as if it were text; this is equivalent
to the --binary-files=text option.

Fastjar -非常古老,但适合你的需要。Fastjar 包含名为 jargrep (或 grepjar)的工具。与 grep 使用相同的方式:

>  locate .jar | grep hibernate | xargs grepjar -n 'objectToSQLString'


org/hibernate/type/EnumType.class:646:objectToSQLString
org/hibernate/sql/Update.class:576:objectToSQLString
org/hibernate/sql/Insert.class:410:objectToSQLString
org/hibernate/usertype/EnhancedUserType.class:22:objectToSQLString
org/hibernate/persister/entity/SingleTableEntityPersister.class:2713:objectToSQLString
org/hibernate/hql/classic/WhereParser.class:1910:objectToSQLString
org/hibernate/hql/ast/tree/JavaConstantNode.class:344:objectToSQLString
org/hibernate/hql/ast/tree/BooleanLiteralNode.class:240:objectToSQLString
org/hibernate/hql/ast/util/LiteralProcessor.class:1363:objectToSQLString
org/hibernate/type/BigIntegerType.class:114:objectToSQLString
org/hibernate/type/ShortType.class:189:objectToSQLString
org/hibernate/type/TimeType.class:307:objectToSQLString
org/hibernate/type/CharacterType.class:210:objectToSQLString
org/hibernate/type/BooleanType.class:180:objectToSQLString
org/hibernate/type/StringType.class:166:objectToSQLString
org/hibernate/type/NumericBooleanType.class:128:objectToSQLString
org/hibernate/type/CustomType.class:543:objectToSQLString
org/hibernate/type/TimeZoneType.class:204:objectToSQLString
org/hibernate/type/DateType.class:343:objectToSQLString
org/hibernate/type/LiteralType.class:18:objectToSQLString
org/hibernate/type/ByteType.class:189:objectToSQLString
org/hibernate/type/LocaleType.class:259:objectToSQLString
org/hibernate/type/CharBooleanType.class:171:objectToSQLString
org/hibernate/type/TimestampType.class:409:objectToSQLString
org/hibernate/type/CurrencyType.class:256:objectToSQLString
org/hibernate/type/AbstractCharArrayType.class:219:objectToSQLString
org/hibernate/type/FloatType.class:177:objectToSQLString
org/hibernate/type/DoubleType.class:173:objectToSQLString
org/hibernate/type/LongType.class:223:objectToSQLString
org/hibernate/type/IntegerType.class:188:objectToSQLString

使用 jfind jar

JFind 可以在文件系统的任何地方找到 Java 类文件,即使 它是隐藏在许多层次深在一个罐子里的耳朵在一个拉链!

Http://jfind.sourceforge.net/

在 android 中,我必须同时搜索 jar 和 aar 文件,才能找到一个特定的字符串,这里是我在 mac 上的实现:

find . -name "*.jar" -o -name "*.aar" | xargs -I{} zipgrep "AssestManager" {}

本质上,以当前直接方式查找所有 jar 和 aar 文件(默认情况下,find 命令是递归的)将结果传送到 zipgrep,并通过 xargs 将每个文件名作为参数应用。最后的括号告诉 xargs 将从 find 命令获得的文件名放在哪里。如果您想搜索整个主目录,只需更改查找。去寻找 ~

在 alvinalexander.com 上找到了下面的脚本。它很简单,但对于搜索工作目录中的所有 jar 文件非常有用

#!/bin/sh


LOOK_FOR="codehaus/xfire/spring"


for i in `find . -name "*jar"`
do
echo "Looking in $i ..."
jar tvf $i | grep $LOOK_FOR > /dev/null
if [ $? == 0 ]
then
echo "==> Found \"$LOOK_FOR\" in $i"
fi
done

将“ codehaus...”替换为查询,即类名。

输出样本:

$ ./searchjars.sh


Looking in ./activation-1.1.jar ...
Looking in ./commons-beanutils-1.7.0.jar ...
Looking in ./commons-codec-1.3.jar ...
Looking in ./commons-pool.jar ...
Looking in ./jaxen-1.1-beta-9.jar ...
Looking in ./jdom-1.0.jar ...
Looking in ./mail-1.4.jar ...
Looking in ./xbean-2.2.0.jar ...
Looking in ./xbean-spring-2.8.jar ...
Looking in ./xfire-aegis-1.2.6.jar ...
Looking in ./xfire-annotations-1.2.6.jar ...
Looking in ./xfire-core-1.2.6.jar ...
Looking in ./xfire-java5-1.2.6.jar ...
Looking in ./xfire-jaxws-1.2.6.jar ...
Looking in ./xfire-jsr181-api-1.0-M1.jar ...
Looking in ./xfire-spring-1.2.6.jar ...
==> Found "codehaus/xfire/spring" in ./xfire-spring-1.2.6.jar
Looking in ./XmlSchema-1.1.jar ...

只有一行程序的解决方案,输出找到搜索字符串的文件名,它不会用不必要的“搜索”日志干扰您的控制台:

find libdir -wholename "*.jar" | xargs --replace={} bash -c 'zipgrep "BEGIN REQUEST" {} &>/dev/null; [ $? -eq 0 ] && echo "{}";'

编辑: : 删除不必要的 if 语句,使用-name 而不是-whole name (实际上,我使用了 whole name,但这取决于您的场景和首选项) :

find libdir -name "*.jar" | xargs --replace={} bash -c 'zipgrep "BEGIN REQUEST" {} &>/dev/null && echo "{}";'

您也可以使用 sh 代替 bash。 最后一件事,—— place = {}就等同于-I {}(我通常使用长选项格式,以避免以后再次进入手册)。

虽然有一些方法可以使用反编译器或者 Eclipse 来实现,但是当这些罐子不是你项目的一部分的时候就会变得很棘手,或者在使用反编译器的时候特别痛苦,因为你有100或者1000个罐子放在几个文件夹里。

我发现 这个 CMD 命令很有用,它可以帮助查找目录中的 jar 列表中的类名。

forfiles /S /M *.jar /C "cmd /c jar -tvf @file | findstr "classname" && echo @path

您可以导航到所需的路径,然后从那里打开 cmd 并运行这个命令,或者直接在命令本身中给出路径,如下所示

forfiles /S /M *.jar /C "cmd /c jar -tvf @file | findstr /C:"classname" && echo @path

我的用例是在 Glassfish 中找到一个特定的类,所以 command 看起来是这样的:

enter image description here