Procurando por uma classe Java em um conjunto de JARs com find, unzip, grep

5

Eu estava tentando encontrar o JAR contendo uma classe Java. Os JARs estão no formato zip.

Minha primeira tentativa foi:

$ 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

Eu encontrei a classe, mas ainda não sei qual dos 25 arquivos correspondentes contém (há dois JARs contendo). Então, pensei em usar tee no meio para gerar os nomes dos arquivos.

$ 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

Eu esperaria ver um nome de arquivo seguido pelo Controller.class para arquivos correspondentes e pelo próximo nome de arquivo para não fazer o mathing. No entanto, agora que penso nisso, a saída padrão apenas flui no pipe e é processada por xargs, portanto, faz sentido.

Eu poderia usar o erro padrão, mas, suponho, como os processos estão sendo executados simultaneamente, eu poderia ter problemas de tempo que deixam a saída fora da ordem que espero ver.

Portanto, deve haver uma maneira melhor de abordar esse problema, alguém tem idéias?

ATUALIZAÇÃO : Enquanto esperava por uma resposta, eu escrevi um horrível forro de Perl que faz o truque, mas estou ansioso para ver soluções mais elegantes.

$ find -name "*3.0.6.RELEASE.jar" | perl -e 'while (<>) { \
    $file=$_; @class='unzip -l $_'; foreach (@class) { \
    if (/stereotype.Controller/) {print "$file $_";} } }'

Saída:

./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
    
por stivlo 28.11.2011 / 07:36

3 respostas

7

Tente isto:

find -name "*3.0.6.RELEASE.jar" -exec sh -c 'unzip -l "{}" | grep -q stereotype.Controller' \; -print

Não há necessidade de xargs ou for loop aqui. Tudo pode ser feito com um único find . Se você quiser também mostrar o conteúdo que obteve grep, apenas remova a opção -q para grep - mas observe que as combinações grep aparecerão antes de cada nome de arquivo. Para uma saída mais clara, você pode adicionar -exec echo \; no final.

    
por 28.11.2011 / 14:12
2

No primeiro one-liner, na opção grep , adicione -H . Isso é incluir o nome do arquivo no resultado.

Aqui está na página do manual -

-H, --with-filename
              Print the filename for each match.</strike>

UPDATE

Pode ser que este script ajude -

#!/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

One-Liner:

for i in 'find . -name "*.jar"'; do jar tvf $i | grep "search pattern" && echo $i ; done

A única parte triste é o nome do arquivo jar que será exibido após o grep content

    
por 28.11.2011 / 09:00
1

Um thread antigo, mas isso parece uma maneira mais simples de fazer isso: link

Windows:
    cpcheck [flags] classpath [classpath]*
Unix:
    ./cpcheck.sh [flags] classpath [classpath]*
Java:
    java -jar cpcheck.jar [flags] classpath [classpath]*
    
por 13.10.2015 / 23:03