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

xargs여기에는 for 또는 루프가 필요 하지 않습니다 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]*

관련 정보