Ok, vamos aplicar a filosofia unix. Quais são os componentes desta tarefa?
- Pesquisa de texto: você precisa de uma ferramenta para pesquisar texto em um arquivo, como
grep
.
- Recursiva: você precisa de uma ferramenta para procurar arquivos em uma árvore de diretórios, como
find
.
- Arquivos: você precisa de uma ferramenta para lê-los.
A maioria dos programas unix opera em arquivos. Portanto, para operar facilmente em componentes de arquivamento, você precisa acessá-los como arquivos, ou seja, é necessário acessá-los como diretórios.
O sistema de arquivos AVFS apresenta uma visão do sistema de arquivos em que cada arquivo /path/to/foo.zip
está acessível como um diretório ~/.avfs/path/to/foo/zip#
. O AVFS fornece acesso somente leitura aos formatos de arquivo mais comuns.
mountavfs
find ~/.avfs"$PWD" \( -name '*.zip' -o -name '*.tar.gz' -o -name '*.tgz' \) \
-exec sh -c '
find "$0#" -name "*.pm" -exec grep "$1" {\} +
' {} 'Test::Version' \;
fusermount -u ~/.avfs # optional
Explicações:
- Monte o sistema de arquivos AVFS.
- Procure por arquivos
~/.avfs$PWD
compactados, que é a visualização AVFS do diretório atual.
- Para cada arquivo morto, execute o snippet de shell especificado (com
$0
= nome do arquivo e $1
= padrão para pesquisar).
$0#
é a visualização do diretório do arquivo morto $0
.
{\}
em vez de {}
é necessária no caso dos exteriores find
substitutos {}
dentro -exec ;
argumentos (alguns o fazem, outros não).
- Opcional: finalmente desmonte o sistema de arquivos AVFS.
Ou em zsh ≥4.3:
mountavfs
grep 'Test::Version' ~/.avfs$PWD/**/*.(tgz|tar.gz|zip)(e\''
reply=($REPLY\#/**/*.pm(.N))
'\')
Explicações:
~/.avfs$PWD/**/*.(tgz|tar.gz|zip)
corresponde aos arquivos na visualização AVFS do diretório atual e de seus subdiretórios.
PATTERN(e\''CODE'\')
aplica CODE a cada correspondência de PATTERN. O nome do arquivo correspondente está em $REPLY
. Definir a reply
matriz transforma a correspondência em uma lista de nomes.
$REPLY\#
é a visualização do diretório do arquivo morto.
$REPLY\#/**/*.pm
corresponde aos .pm
arquivos no arquivo morto.
- O
N
qualificador glob faz com que o padrão se expanda para uma lista vazia se não houver correspondência.