Может быть, лучше всего начать с варианта использования.
У меня большой zip-файл, заполненный множеством файлов, и я подозреваю, что он изначально был заархивирован с низким уровнем сжатия.

Я хочу создать новый zip-файл из этого файла (или не новый, мы надеемся, на месте), чтобы убедиться, что он хорошо сжат (-9) без необходимости сначала разархивировать его на диск (по различным причинам, таким как размер и наличие смонтированной NFS). Так что пока я мог просто сделать

mkdir tmp/ && unzip -d tmp/ A.zip && cd tmp/ && zip -r -9 ../B.zip *; rm -rf tmp/ A.zip

Это [временно] создаст огромное количество данных (распакованные файлы и B.zip появятся до A.zip ).
Я бы очень хотел что-то вроде:

rezip -9 A.zip

или, соглашаясь на B.zip:

unzip -<output to stdout> A.zip | zip -9 B.zip && rm -f A.zip

Но я понимаю, что это на самом деле невозможно, так как канал будет использоваться для нескольких файлов, и такие вещи, как имена файлов, будут потеряны.

Итак, мне интересно, есть ли способ выполнить некоторый код для каждого файла, например, find -exec <command>

unzip A.zip -exec zip -r B.zip && rm -f A.zip

Но опять же, не знаете, как это будет работать, или, если это не облегчается при помощи unzip/zip , существует ли команда, которая это делает.

В качестве ответа я включил мой текущий, все еще использующий временные решения для отдельных файлов файл, поскольку он может помочь кому-то, хотя и не будет принят, поскольку он не отвечает на вопрос о том, что временные интервалы не допускаются.

3 ответа3

0

Это было давно, но вот как ты это делаешь.
Работает для файлов с пробелами в имени и подкаталогах.

zipinfo -1 A.zip | while read filename
do
    unzip -p A.zip "$filename" | zip -9 A.zip -
    zip --delete A.zip "$filename"
    printf "@ -\n@=$filename\n" | zipnote -w A.zip
done
0

Я нашел лучшее решение:

unzip -p original.zip | zip -9 new.zip -

unzip -p указывает unzip отправлять вывод на стандартный вывод. Последняя черта команды zip говорит ей читать со стандартного ввода.

Вам все еще нужно переименовать new.zip в original.zip, если вам это действительно нужно.

0

У проекта с открытым исходным кодом Zip-Ada есть именно такой инструмент для распаковки.

  1. получить / скачать исходники
  2. сборка с помощью команды gnatmake -P zipada (вы получаете GNAT через apt или yum)
  3. Теперь у вас есть бинарный архив со следующими параметрами:

,

Usage: rezip [options] archive(s)[.zip]

Options:  -defl     : repack archive only with the Deflate
                    subformat (most compatible)
          -fast_dec : repack archive only with fast decompressing subformats
          -int      : use internal Zip-Ada algorithms only, no external call
          -touch    : set time stamps to now
          -lower    : set full file names to lower case
          -del_comm : delete comment
          -comp     : compare original and repacked archives (paranoid mode)
          -rs=n     : loop many times over a single compression approach
                        having randomization, and keep optimum when size is
                        stable after n attempts in a row

Для начала я рекомендую использовать -defl и -int (в частности, -defl будет поддерживать полученный Zip-файл совместимым со старыми инструментами, такими как unzip).

Команда будет, например, ./rezip -int -defl -comp A.zip

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .