É possível no unix pesquisar dentro de arquivos zip

6

Eu tenho centenas de diretórios e dentro deles eu tenho alguns arquivos zip. Agora existem imagens chamadas abc.jpg nesses arquivos zip. Os arquivos zip podem estar em qualquer pasta ou em qualquer subpasta, então é difícil extraí-los em um só lugar.

Eu só quero coletar esses arquivos de imagem. Isso é possível?

    
por Mirage 26.04.2011 / 15:42

4 respostas

4

Uma vez precisei de algo semelhante para encontrar arquivos de classe em vários arquivos zip. Aqui está:

#!/bin/bash

function process() {
while read line; do
    if [[ "$line" =~ ^Archive:\s*(.*) ]] ; then
        ar="${BASH_REMATCH[1]}"
        #echo "$ar"
    else
        if [[ "$line" =~ \s*([^ ]*abc\.jpg)$ ]] ; then
            echo "${ar}: ${BASH_REMATCH[1]}"
        fi
    fi
done
}


find . -iname '*.zip' -exec unzip -l '{}' \; | process

Agora você só precisa adicionar uma linha para extrair os arquivos e movê-los. Não sei exatamente o que você quer fazer, então deixarei isso para você.

    
por 26.04.2011 / 16:35
3

Se a sua variante unix suporta FUSE (Linux, * BSD, OSX, todos do Solaris), monte AVFS para acessar arquivos de forma transparente. O comando mountavfs cria uma visualização de todo o sistema de arquivos, com raiz em ~/.avfs , em que os arquivos archive possuem um diretório associado que contém os diretórios e arquivos no archive. Por exemplo, se você tiver foo.zip no diretório atual, o comando a seguir será equivalente a unzip -l foo.zip :

mountavfs    # needs to be done once and for all
find ~/.avfs$PWD/foo.zip\# -ls

Portanto, faça o loop de todas as imagens contidas em um arquivo zip no diretório atual e copie-as para /destination/directory (com um prompt em caso de conflito):

find ~/.avfs"$PWD" -name '*.zip' -exec sh -c '
    find "${0}#" -name "*.jpg" -exec cp -ip {} "$1" \;
' {} /destination/directory \;

No zsh:

cp -ip ~/.avfs$PWD/**/*.zip(e\''REPLY=($REPLY\#/**/*.jpg(N))'\') /destination/directory

Desconstrução: ~/.avfs$PWD/**/*.zip expande para a exibição do AVFS dos arquivos zip no diretório atual. O qualificador glob e é usado para modificar a saída do glob: …/*.zip(e\''REPLY=$REPLY\#'\') apenas acrescentaria um # a cada correspondência. REPLY=($REPLY\#/**/*.jpg(N)) transforma cada correspondência na matriz de .jpg arquivos no diretório .zip# .

    
por 26.04.2011 / 16:23
1

Eu suponho que você tenha uma nova versão do Bash, então você deve poder usar isto:

shopt -s globstar
for path in topdir/**/*.zip
do
    unzip "$path" '.*abc.jpg'
done
    
por 26.04.2011 / 16:38
1

Semelhante à resposta do Kims, mas ligeiramente modificada. Apenas use sed :

find . -name *.zip -exec unzip -l '{}' \; | sed -n -e '/^Archive/ {h}' -e '/abc.jpg$/ {x;p;x;}'
    
por 22.11.2013 / 12:42