(Adaptado de Como eu grep recursivamente através de arquivos compactados? )
Instale o AVFS , um sistema de arquivos que fornece acesso transparente dentro dos arquivos. Primeiro, execute este comando uma vez para configurar uma visão do sistema de arquivos da sua máquina no qual você pode acessar os arquivos como se fossem diretórios:
mountavfs
Depois disso, se /path/to/archive.zip
for um arquivo reconhecido, ~/.avfs/path/to/archive.zip#
é um diretório que parece conter o conteúdo do arquivo.
find ~/.avfs"$PWD" \( -name '*.7z' -o -name '*.zip' -o -name '*.tar.gz' -o -name '*.tgz' \) \
-exec sh -c '
find "$0#" -name "*vacation*.jpg"
' {} 'Test::Version' \;
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).
Ou em zsh ≥4.3:
mountavfs
ls -l ~/.avfs$PWD/**/*.(7z|tgz|tar.gz|zip)(e\''
reply=($REPLY\#/**/*vacation*.jpg(.N))
'\')
Explicações:
~/.avfs$PWD/**/*.(7z|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\#/**/*vacation*.jpg
corresponde aos *vacation*.jpg
arquivos no arquivo morto.
- O
N
qualificador global faz com que o padrão se expanda para uma lista vazia, se não houver correspondência.
Gilles 'SO- parar de ser mau'
fonte
Minha solução usual :
Exemplo:
Os resultados são como:
Se você deseja apenas o arquivo zip com hits :
O nome do arquivo aqui é usado duas vezes, para que você possa usar uma variável.
Com o find, você pode usar PATH / TO / SEARCH
fonte
Outra solução que funciona é
zgrep
fonte
zgrep
é essa? Isso não funciona com aquele fornecido com o GNUgzip
(/bin/zgrep: -r: option not supported
,zgrep (gzip) 1.6
)A facilidade de uso do IMHO deve ser algo importante também:
e para alcatrão (este não foi testado ...)
fonte
unzip
implementação pode lidar com arquivos 7z ou tar.gz?libarchive
'sbsdtar
podem lidar com a maioria desses formatos de arquivo, assim que você poderia fazer:Com o que você pode simplificar (e melhorar para corresponder a maiúsculas e minúsculas) com o GNU
find
:Isso não imprime o caminho do arquivo onde esses
*vacation*jpg
arquivos são encontrados. Para imprimir esse nome, você pode substituir a última linha por:que fornece uma saída como:
Ou com
zsh
:Note-se que há uma série de outros formatos de arquivo que são apenas
zip
outgz
arquivos disfarçados como.jar
ou.docx
arquivos. Você pode adicioná-los ao seu padrãofind
/zsh
pesquisa,bsdtar
não se importa com a extensão (como em, ele não depende da extensão para determinar o tipo do arquivo).Observe que
*vacation*.jpg
acima é correspondido no caminho completo do membro do arquivamento, não apenas no nome do arquivo; portanto, ele corresponderá,vacation.jpg
mas também ativarávacation/2014/file.jpg
.Para corresponder apenas ao nome do arquivo, um truque seria usar o modo de extração , use
-s
(substituição) que usa regexps com ump
sinalizador para imprimir os nomes dos arquivos correspondentes e, em seguida, verifique se nenhum arquivo foi extraído, como:Note que ele produziria a lista no stderr e acrescentaria
>>
a cada linha. De qualquer forma ,,bsdtar
como a maioria dastar
implementações, os nomes dos arquivos são mostrados se eles contiverem caracteres como nova linha ou barra invertida (renderizada como\n
ou\\
).fonte