Como faço para compactar vários arquivos na linha de comando?

7

Perdoe essa pergunta básica, mas não consegui encontrar uma resposta direta ou um exemplo simples de troca de pilha.

Digamos que eu tenha uma pasta de arquivos que eu gostaria de compactar em um arquivo zip que eu possa compartilhar com meus péssimos amigos do Windows (senão usaria tar e terminaria com isso). Parece assim:

.
├── file1.txt
├── file2.txt
├── file3.txt
├── file.jpg
└── test.jpg

Supondo que eu tenha zip instalado:

sudo apt-get install zip

Eu vejo do man zip que isso me permite usar uma lista de arquivos:

  

- @ listas de arquivos. Se uma lista de arquivos é especificada como - @ [Not on MacOS], o zip pega a lista de arquivos de entrada          da entrada padrão em vez da linha de comando. Por exemplo,

          zip -@ foo

Então eu criei zip.lst , que é assim:

cat zip.lst

file1.txt
file2.txt
file3.txt
file.jpg
test.jpg

E agora eu tentei:

zip -@ zip.lst

Mas ele não fez nada, exceto criar uma linha em branco no console. E eu posso continuar pressionando Enter e ele continua criando mais linhas em branco sem aparentemente executar o comando. Após algumas pesquisas, percebi que precisava terminar a entrada pressionando Ctrl + D

Mas agora recebo este erro:

    zip warning: missing end signature--probably not a zip file (did you
    zip warning: remember to use binary mode when you transferred it?)
    zip warning: (if you are trying to read a damaged archive try -F)

zip error: Zip file structure invalid (zip.lst)

O quê? Como minha lista simples não é uma "estrutura de arquivo válida"? De volta ao manual para mais informações, e eu dou uma olhada mais de perto:

  

Se uma lista de arquivos é especificada como - @ ...

Então eu tento sem -@ , e isso pelo menos o processa imediatamente sem ter que pressionar Ctrl + D mas eu fico com o mesmo erro .

Por sorte, eu encontrei um comentário em uma resposta a uma pergunta quase não relacionada que me levou a perceber que eu precisava nomeie explicitamente o arquivo zip. Este erro ocorreu porque, por padrão, ele estava tentando criar um arquivo zip chamado zip.lst . Mas como esse é o nome da minha lista, pode-se pensar que seria simplesmente sobrescrevê-la, mas não, na verdade, estava tentando atualizá-la. E como a lista obviamente não é um arquivo zip, obtemos o erro de estrutura de arquivo inválido e agora fica claro por que ele dizia "provavelmente não é um arquivo zip". Então tentei:

zip files.zip zip.lst

adding: zip.lst (deflated 35%)

Eureka! Eu posso ver que o arquivo zip foi criado e minha pasta agora contém:

.
├── file1.txt
├── file2.txt
├── file3.txt
├── file.jpg
├── files.zip
├── test.jpg
└── zip.lst

Mas espere antes de comemorar, vamos confirmar primeiro o conteúdo do arquivo zip:

unzip -l files.zip

Archive:  files.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
       48  2016-05-24 15:30   zip.lst
---------                     -------
       48                     1 file

Não! Bem, na verdade isso faz sentido a partir do uso padrão, porque ele apenas compactou o arquivo de uma lista que eu forneci. Por fim, tentei novamente com -@ , mas obtive o mesmo resultado.

O que estou fazendo de errado?

BTW, eu sei que posso usar a GUI e fazer isso com o mouse, mas preciso roteirizar isso e, em geral, sou mais rápido na CLI quando sei o que estou fazendo.

    
por Jeff Puckett 25.05.2016 / 00:30

2 respostas

8

Fico feliz em responder minha própria pergunta porque queria registrar minha turbulência na esperança de que os outros acompanhassem o problema. por trás do meu rasto de lágrimas poderia ser poupado por procurar algumas palavras-chave.

Por fim, descobri a resposta certa , mas foi postada para a pergunta errada .

Alguns pontos de clareza:

  • O manual não está se referindo a uma lista literal como em um arquivo, mas literalmente ao listar os arquivos no console.
  • É compreensível que alguém possa ser levado a pensar que foo se referiu à lista de arquivos, mas na verdade pretende representar o nome do arquivo zip de saída.
  • A lista de arquivos é omitida no exemplo porque está usando a opção -@ , que demonstra que "pega a lista de arquivos de entrada da entrada padrão em vez da linha de comando "

Compreendendo isso, agora estamos armados com uma variedade de maneiras de atingir a meta.

Primeiramente usando a lista de arquivos que criamos, podemos ler a lista com cat e redirecionar a saída com um pipe como entrada padrão para zip:

cat zip.lst | zip -@ files.zip

  adding: file1.txt (stored 0%)
  adding: file2.txt (stored 0%)
  adding: file3.txt (stored 0%)
  adding: file.jpg (stored 0%)
  adding: test.jpg (stored 0%)

Ver que adding: ... para cada arquivo é certamente um bom sinal, mas esperávamos antes, então vamos confirmar:

unzip -l files.zip

Archive:  files.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2016-05-24 14:54   file1.txt
        0  2016-05-24 14:54   file2.txt
        0  2016-05-24 14:54   file3.txt
        0  2016-05-24 15:00   file.jpg
        0  2016-05-24 14:59   test.jpg
---------                     -------
        0                     5 files

SWEET! Mas quem quer criar uma lista de uso único de qualquer maneira? Essa é uma maneira terrível de resolver esse cenário em particular. Seria melhor obter uma lista de ls e canalizar isso para zipar:

ls | zip -@ files.zip

  adding: file1.txt (stored 0%)
  adding: file2.txt (stored 0%)
  adding: file3.txt (stored 0%)
  adding: file.jpg (stored 0%)
  adding: test.jpg (stored 0%)

Fabuloso! Agora vamos criar filtros com o incrível poder de grep para apenas fechar o jpg por exemplo:

ls | grep .jpg | zip -@ images.zip

  adding: file.jpg (stored 0%)
  adding: test.jpg (stored 0%)

Ou apenas arquivos que começam com "arquivo"

ls | grep file. | zip -@ files.zip

  adding: file1.txt (stored 0%)
  adding: file2.txt (stored 0%)
  adding: file3.txt (stored 0%)
  adding: file.jpg (stored 0%)
    
por Jeff Puckett 25.05.2016 / 00:30
5

o comando mais simples com o nível de compactação máxima

zip -9 -r filename.zip /path/to/dir singlefile.jpg 
    
por Ansyori 09.05.2017 / 10:41

Tags