Распаковать файл без создания временных файлов

350
Hashbrown

Может быть, лучше всего начать с варианта использования.
У меня большой 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, существует ли команда, которая делает это.

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

0

1 ответ на вопрос

0
Hashbrown

Это так близко, как я мог получить

zipinfo -1 A.zip |  xargs -l sh -c ' unzip A.zip "$0" && zip -9 A.zip "$0";  rm -f "$0" ' 

Который только когда-либо создает один файл tmp для каждого файла в zip за один раз.
Если я смогу найти способ заархивировать stdinи передать имя файла, я смогу использовать распаковку, -pчтобы вместо этого использовать каналы полностью.

zipinfo -1 A.zip |  xargs -l sh -c ' unzip -p A.zip "$0" |  zip -9 A.zip -<use this filename> "$0" ' 

Но это сложно

Похожие вопросы