Existe uma maneira de compactar todos os arquivos em um determinado diretório com o comando zip? Já ouvi falar do uso de *.*, mas também quero que funcione para arquivos sem extensão.

Comentários

  • Você já tentou navegar um nível acima do diretório desejado e fazer zip myarch.zip mydir/*?
  • ou melhor zip -r myarch.zip mydir/*
  • ou melhor zip -r myarch.zip mydir
  • *.* significa qualquer arquivo com um ponto. Em cp / m e dos todos os arquivos tinham um ponto, e isso obrigou você a digitá-lo (não foi possível *). Portanto, as pessoas vieram ver *.* como todos os arquivos. Eventualmente, a Microsoft adicionou nomes de arquivo longos que podem ter zero ou mais pontos. Para encontrar um arquivo com um ponto nas janelas, você deve digitar *.*.*.

Resposta

Você pode apenas usar *; não há necessidade para *.*. As extensões de arquivo não são especiais no Unix. * corresponde a zero ou mais ch caracteres – incluindo um ponto. Portanto, corresponde a foo.png, porque é zero ou mais caracteres (sete, para ser exato).

Observe que * por padrão não corresponde a arquivos que começam com um ponto (nem *.*). Geralmente é isso que você deseja. Do contrário, no bash, se você shopt -s dotglob irá (mas ainda excluirá . e ..). Outros shells têm maneiras diferentes (ou nenhuma) de incluir dotfiles.

Como alternativa, zip também tem um -r opção (recursiva) para fazer árvores de diretório inteiras de uma vez (e não precisa se preocupar com o problema do dotfile):

zip -r myfiles.zip mydir 

where mydir é o diretório que contém seus arquivos. Observe que o zip produzido conterá a estrutura do diretório, bem como os arquivos. Como peterph aponta em seu comentário, isso geralmente é visto como uma coisa boa: extrair o zip irá armazenar ordenadamente todos os arquivos extraídos em um subdiretório.

Você também pode dizer ao zip para não armazenar os caminhos com o opção -j / --junk-paths.

O comando zip vem com documentação informando sobre todas as suas (muitas) opções; digite man zip para ver essa documentação. Isso não é exclusivo do zip; você pode obter documentação para a maioria dos comandos desta forma.

Comentários

  • Você pode querer adicionar, que é considerado uma boa prática conter tudo no arquivo em um diretório de nível superior – para que não ‘ polua seu diretório atual na extração.
  • @peterph done. Embora isso seja menos uma convenção em arquivos zip do que em tarfiles, ‘ estou com medo.
  • infelizmente sim. Provavelmente devido às janelas herança de arrastar ‘ n ‘ soltar na área de trabalho e herança do Linux de trabalhar com códigos-fonte.
  • Mantenha-se atento lembre-se de que * shell-globbing não ‘ inclui dotfiles (ou seja, nomes de arquivos começando com .). Esta é outra vantagem de compactar todo o diretório por nome.
  • Mas usar -r inclui o próprio diretório, o que quebra o que eu ‘ estou fazendo. Não ‘ * incluiria . e ..?

Resposta

No meu caso, eu queria compactar cada arquivo em seu próprio arquivo, então fiz o seguinte (em zsh):

$ for file in *; do zip ${file%.*}.zip $file; done 

Comentários

  • Existem ‘ s não mkv aqui? Além disso, nada aqui é particularmente zsh específico. Você ‘ desejará citar adequadamente qualquer variável que contenha um nome de arquivo, então zip "${file%.*}.zip" "$file" com aspas duplas em torno de ambas as variáveis.
  • @tripleee Em primeiro lugar, obrigado por apontar minha referência errada a mkv. Em segundo lugar, citar argumentos é desnecessário em zsh, ao contrário de bash. É ‘ por isso que especifiquei que este era um comando para zsh.
  • Substituindo o último ponto e vírgula por um e comercial pode acelerar significativamente (se o número de arquivos no diretório for razoável …). Caso contrário, find . -type f -maxdepth 1 -print0|xargs -r0 -n1 -P64 -I{} bash -c 'f="{}"; zip "${f%.*}.zip" "$f"' (com -P ajustado dependendo de seus threads de CPU …) (Muitas dependências GNU …)
  • para compactar cada arquivo em seu próprio arquivo, gzip *

Resposta

Outra maneira seria usar find e xargs: (isso pode incluir um diretório “.” no zip, mas ainda deve extrair corretamente. Com meu teste, o zip removeu o ponto antes compressão) find . -type f -exec zip zipfile.zip {} +

(O + pode ser substituído por \; se sua versão de find não for compatível com o + final para exec. Porém, será mais lento …)

Por padrão, isso incluirá todos os subdiretórios. No GNU, encontre -maxdepth pode evitar isso.

Comentários

  • (ao contrário das soluções que usam *, isso incluirá dotfiles e não ‘ cairá se houver muitos arquivos em um diretório)

Resposta

Outro método (lento) para fazer isso (que adiciona um arquivo ao zip por vez):

for f in * .[^.]*; do [ -r "$f" ] || continue # Skip directories or non-existant files (Probably ".[^.]*" if directory has no dotfiles). Using -e will allow directories to be used as well zip zipfile.zip "$f" # If directories are included, you probably want to add -r done 

Isso tem os problemas de dotfile de * (solução alternativa adicionada) e seria iniciar zip uma vez para cada arquivo, adicionando-o ao arquivo. Em bash, ele lidaria com uma grande quantidade de arquivos.

Seria mais lento do que a maioria dos outros métodos, mas é relativamente simples.

Comentários

  • Eu diria que é menos simples do que a resposta aceita e mais lenta, o que leva à pergunta: ” Por que alguém faria isso? “. Se você puder responder a essa pergunta, recomendo que coloque esse contexto em sua resposta, caso contrário, acho que é uma resposta ruim para uma pergunta antiga que já tem uma boa resposta.
  • @Centimane: Eu noto as limitações . Eu sinto que isso tem valor educacional. (Se não estiver pulando diretórios, é bastante simples). Se você quiser uma resposta muito mais rápida usando uma ferramenta externa (padrão), minha outra resposta cobre isso. (com o manuseio de dotfiles removido (o que afeta a correção sem sua ausência mencionada na pergunta), acho que é bastante elegante): for f in *; do zip zip.zip "$f"; done
  • Observe que o aceito A resposta não ‘ não usa um comando externo e seria mais rápida. Em que cenário esta resposta seria útil?
  • @Centimane Com tar quando há mais arquivos do que o bash pode passar como parâmetros. (find + xargs são melhores, pois loops são mais fáceis …). É uma resposta (única) à pergunta. Certamente não é a resposta ideal. (Respostas não ótimas ainda podem ser úteis para problemas semelhantes, se alguém tiver uma situação ligeiramente diferente – por exemplo, querer o arquivo tar em qualquer diretório nele)

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *