sexta-feira, 3 de agosto de 2007

Caçadores da Classe Perdida

Eu já tinha feito algo parecido mas este post do Claudio Miranda reavivou a minha memória.

#!/bin/bash
[[ $2 ]] || { echo "Uso: ${0} diretorio classe" ; exit 1 ; }
find "${1}" -name \*.jar -print | xargs -n 1 unzip -l 2>&- | awk -v class="${2}" '
BEGIN { IGNORECASE=1 }
/^Archive/ { file="\nArquivo:\n\t"$NF": \nClasses:\n\t" }
/class$/ && $NF ~ class { print file,$NF ; file="\t"; total++ }
END { print "\nTotal",total + 0,"classes encontradas!" }'


Informando como parâmetros um diretório de partida e um fragmento do nome da classe, o find localizará todos os arquivos com extensão jar e vai mandar pro nosso amigo xargs. Este envia um a um para o unzip que lista (-l) o conteúdo de cada arquivo. Eu poderia procurar a classe que eu quero com o grep, mas o awk foi a escolha para formatar melhor a saída de dados.

Perceba que a variavel IGNORECASE tem valor diferente de 0, assim eu posso procurar por um trecho do tipo xml ou XML. Eu preciso saber o nome do arquivo 'corrente' e isso é informado pela linha que começa com 'Archive'. Quando eu encontro uma linha que termina com 'class' e o ultimo campo ( $NF ) 'casa' com o fragmento de nome (alias pode ser uma expressão regular!) eu imprimo esta linha.

Eu fiz uma sacanagem pra saída de dados ficar 'bonitinha', que é imprimir o 'cabeçalho' apenas uma vez, depois eu troco por tab (\t) -- e no final eu mostro um sumário com o número de referências encontradas.

Este script pode ser modificado para outros propósitos. Note que eu procuro tanto no nome da classe quando no nome dos pacotes (diretórios), assim xml poderia casar com XMLHelper.class ou /java/xml/foobar.jar -- mas basta ser criativo para resolver isso!

2 comentários:

Claudio Miranda disse...

Olá Tiago, obrigado pela dica-dica e manter a formatação de saída. Vou aprender um pouco mais de AWK.

Tiago Peczenyj disse...

AWK é extremamente versátil!