comando para compactar vários diretórios em arquivos zip individuais

40

Eu tenho um único diretório que contém dezenas de diretórios dentro dele.

Eu sou novo na linha de comando e estou lutando para criar um comando que compactará cada subdiretório em um arquivo subdiretório.zip exclusivo.

Portanto, no final, meu diretório principal será preenchido com todos os meus subdiretórios originais, além dos .ziparquivos correspondentes que contêm o conteúdo compactado de cada subdiretório.

É algo assim possível? Se sim, por favor, mostre-me como é feito.

Evster
fonte
Eu sugiro que você veja como "para loops" pode ser feito no shell. Existem on-line que podem fazer o que você deseja, mas um bom loop será muito mais claro.
lynxlynxlynx
Isso significa que eu preciso escrever um script de shell separado e chamá-lo na linha de comando? Desculpe por uma pergunta tão elementar. Embora eu tenha alguma experiência em programação, essas coisas são novas para mim.
Evster 19/03/2013

Respostas:

75

Você pode usar esse loop em bash:

for i in */; do zip -r "${i%/}.zip" "$i"; done

ié o nome da variável de loop. */significa todos os subdiretórios do diretório atual e incluirá uma barra final nesses nomes. Certifique-se de cdestar no lugar certo antes de executar isso. "$i"simplesmente nomeia esse diretório, incluindo a barra final. As aspas garantem que os espaços em branco no nome do diretório não causem problemas. ${i%/}é semelhante, $imas com a barra final removida, para que você possa usá-lo para construir o nome do arquivo zip.

Se você quiser ver como isso funciona, inclua um echoantes de zipe você verá os comandos impressos em vez de executados.

MvG
fonte
Graças isso parece ótimo! No entanto, pensei em um problema em potencial: isso compactará TODOS os diretórios dentro de cada subdiretório em arquivos separados? Eu só quero compactar os subdiretórios de 1º nível como arquivos compactados únicos. Não quero criar arquivos zip adicionais para subdiretórios de segundo e terceiro nível, etc ... Por favor, deixe-me saber se isso faz sentido. Obrigado novamente!
Evster 19/03/2013
Somente os de primeiro nível, como você solicitou.
Lynxlynxlynx
Os */nomes de todos os subdiretórios diretos, não de todos os diretórios descendentes. Portanto, você só terá zíperes para o nível superior, do jeito que você quiser. A versão echonele teria demonstrado esse aspecto. Compactar todo diretório aninhado em seu próprio arquivo seria de fato mais trabalhoso e, provavelmente, melhor resolvido usando find -type doutros truques.
MvG 19/03/2013
11
@fritzmg: Um teste local no meu Linux sugere que sim, arquivos iniciados em um ponto estão incluídos. Isso seria uma propriedade da ferramenta Info-ZIP, não do comando que eu dei, portanto, dependendo do seu zipbinário, você poderá ter um comportamento diferente. Para criar também arquivos zip para diretórios de nível superior (ou seja, filhos do diretório atual) começando com um ponto, você pode usar shopt -s dotglobpara fazer com que os padrões globais correspondam também aos arquivos ocultos.
MvG 13/08/19
11
Para criar um zip que não tem o diretório pai como sua raiz:for i in */; do (cd "$i"; zip -r "../${i%/}.zip" .); done
chris