Как обновить один файл в zip-архиве

86

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

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

Так можно ли просто заменить один xml без разархивирования и повторного сжатия?

Извините, я бы использовал команду zip для таких вещей, но проблема в том, что скрипт на самом деле предназначен для телефона Android, а zip не является командой, которую я могу использовать, к сожалению, извините, я пропустил это. Я бы определенно использовал zip, если бы мог, но у меня есть только распаковка для droid, а затем в busybox есть tar, но tar не делает то, что мне нужно

user577732
источник
3
вы можете изменить заголовок вопроса на более содержательный?
tokland
7
Кроме того, вопрос мог состоять из одного или двух предложений. Около 80% из них бессвязно.
Приостановлено до дальнейшего уведомления.

Ответы:

62

Из застежки-молнии (1) :

При присвоении имени существующего zip-архива zip заменяет записи с одинаковыми именами в zip-архиве или добавляет записи для новых имен.

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

Пожалуйста
источник
5
Кто-нибудь может привести пример? Я не понимаю помощи команды zip.
Гюстав,
12
Допустим, вы заархивировали мою папку, используя, zip -r myfolder.zip myfolderесли хотите обновить myfolder/otherfolder/myfile.txt, отредактируйте файл и запуститеzip -r myfolder.zip myfolder/otherfolder/myfile.txt
eakkas
1
Как это сделать, если заменяемый файл не имеет того же имени и структуры, что и файл, который нужно заменить?
Fractaliste
2
@Fractaliste Вы должны сделать так, чтобы он имел такое же имя и структуру;)
Hack5
72

Я обнаружил, что zipфайл Linux является громоздким для замены одного файла в zip-архиве. jarУтилита из комплекта Java Development Kit может быть проще. Рассмотрим обычную задачу обновления WEB/web.xmlв файле JAR (который является просто файлом zip):

jar -uf path/to/myapp.jar -C path/to/dir WEB-INF/web.xml

Здесь path/to/dirпуть к каталогу, содержащему WEB-INFкаталог (который, в свою очередь, содержит web.xml).

Cayhorstmann
источник
что, если мне нужно скопировать только файл, а не создавать директора, у WEB-INFкоторого есть этот файл.
Helping hand
Также в моем случае добилась своего успеха старая дорогая утилита "jar"! Благодарность!
bitfox
51

Попробуйте следующее:

zip [zipfile] [file to update] 

Пример:

$ zip test.zip test/test.txt
updating: test/test.txt (stored 0%)
WizardsOfWor
источник
2
Это самый простой для понимания пример, спасибо!
vatsug 01
2
Учтите, что вы должны увидеть updating:вместо того adding:, чтобы обновить файл внутри zip-архива; в противном случае вы добавляете файлы в zip-архив, а не заменяете его.
Edenshaw
Вы правы, я этого не заметил. Обновлено, спасибо!
WizardsOfWor
13

Я знаю, что это старый вопрос, но я хотел сделать то же самое. Обновите файл в zip-архиве. И ни один из приведенных выше ответов мне не помог.

Вот что я сделал. Создан временный каталог abc. Скопировано file.zipв abcи извлеченный файл в этом каталоге. Я отредактировал файл, который хотел отредактировать. Затем, находясь внутри abc, выполнила следующую команду

user@host ~/temp/abc $ zip -u file.zip
updating: content/js/ (stored 0%)
updating: content/js/moduleConfig.js (deflated 69%)

-u переключатель будет искать измененные / новые файлы и добавлять их в zip архив.

традиционный
источник
11

Используйте флаг обновления: -u

Пример:

zip -ur existing.zip myFolder

Эта команда сожмет и добавит myFolder(и его содержимое) в файл existing.zip.


Расширенное использование:

Флаг обновления фактически сравнивает входящие файлы с существующими и либо добавляет новые файлы, либо обновляет существующие.

Поэтому, если вы хотите добавить / обновить определенный подкаталог в zip-файле, просто обновите источник по своему усмотрению, а затем повторно заархивируйте весь источник с помощью -uфлага. Будут заархивированы только измененные файлы.

Если у вас нет доступа к исходным файлам, вы можете разархивировать zip-файл, затем обновить нужные файлы, а затем повторно заархивировать с -uфлагом. Опять же, будут заархивированы только измененные файлы.

Пример:

Исходная исходная структура


ParentDir
├── file1.txt
├── file2.txt
├── ChildDir
│   ├── file3.txt
│   ├── Logs
│   │   ├── logs1.txt
│   │   ├── logs2.txt
│   │   ├── logs3.txt

Обновленная структура источника


ParentDir
├── file1.txt
├── file2.txt
├── ChildDir
│   ├── file3.txt
│   ├── Logs
│   │   ├── logs1.txt
│   │   ├── logs2.txt
│   │   ├── logs3.txt 
│   │   ├── logs4.txt <-- NEW FILE 

Применение

$ zip -ur existing.zip ParentDir 
> updating: ParentDir/ChildDir/Logs (stored 0%)
>   adding: ParentDir/ChildDir/Logs/logs4.txt (stored 96%)
Итан Страйдер
источник
5

Вы можете использовать: zip -u file.zip path / file_to_update

Ренато Луис Рамос
источник
1

Также есть опция -f, которая обновит zip-файл. Его можно использовать для обновления ВСЕХ файлов, которые были обновлены с момента создания zip-архива (при условии, что они находятся в одном месте в древовидной структуре внутри zip-файла).

Если ваш файл называется /myfiles/myzip.zip, все, что вам нужно сделать, это

zip -f /myfiles/myzip.zip
гвроча
источник
0

Со стороны структуры ZIP-архива - вы можете обновить zip-файл без его повторного сжатия, вам просто нужно будет пропустить все файлы, предшествующие файлу, который вам нужно заменить, затем поместить обновленный файл, а затем остальные файлы. И, наконец, вам нужно будет разместить обновленную центральную структуру каталогов. Однако я сомневаюсь, что большинство обычных инструментов позволят вам это сделать.

Николай Ольшевский
источник
0

7zip (7za) можно использовать для добавления / обновления файлов / каталогов:

Пример: замена (независимо от даты файла) MANIFEST.MFфайла в файле JAR. /source/META-INFКаталог содержит MANIFEST.MFфайл , который вы хотите поместить в jar(почтовый индекс):

7za a /tmp/file.jar /source/META-INF/

Только обновление (не заменяет цель, если источник старше)

7za u /tmp/file.jar /source/META-INF/
mzsolt
источник
-2

да это возможно.

в системах на базе Linux просто установите zip, и вы можете вызвать его из командной строки. взгляните на страницу руководства: http://linux.die.net/man/1/zip

но по моему личному опыту, если возможно и сжатие не так важно, это лучше работает с простыми файлами tar и tar.

Surrican
источник