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