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個の一致するファイルのうち、どのファイルにそのクラスが含まれているかはまだわかりません(このクラスを含む2つの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

xargsこれにはforやループは必要ありませんfor。これはすべてを介して行うことができますfind。 grepの内容も出力したい場合は削除してください-qgrepただし、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

1本のライン:

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

関連情報