Jak zaktualizować jeden plik w archiwum zip

86

Czy można zamienić plik w archiwum zip bez rozpakowywania, usuwania starego pliku, dodawania nowego pliku i ponownego załadowania go z powrotem?

Powodem jest to, że mam plik zip, który jest naprawdę duży, w pliku zip znajduje się jeden xml, który muszę czasami aktualizować. Rozpakowanie zamka błyskawicznego i ponowne załadowanie zajmuje dużo czasu. Więc chciałbym móc po prostu zamienić jeden plik XML w pliku zip za pomocą skryptu. Mam już to sprawdza dostępność aktualizacji w pliku XML, który mam.

Czy można więc po prostu zastąpić jeden plik XML bez rozpakowywania i ponownego rozpakowywania?

Przepraszam, że użyłbym polecenia zip do zrobienia takich rzeczy, ale problem polega na tym, że skrypt jest w rzeczywistości przeznaczony dla telefonu z systemem Android, a zip nie jest poleceniem, którego mogę użyć niestety, przepraszam, że go pominąłem. Na pewno użyłbym zip, gdybym mógł, ale mam tylko rozpakowywanie dla droida, a potem jest tar w busybox, ale tar nie robi tego, czego potrzebuję

user577732
źródło
3
czy możesz zmienić tytuł pytania na coś bardziej znaczącego?
tokland,
7
Ponadto pytanie mogło być jednym lub dwoma zdaniami. Około 80% z tego to wędrowanie.
Wstrzymano do odwołania.

Odpowiedzi:

62

Z zip (1) :

Gdy podana zostanie nazwa istniejącego archiwum zip, zip zastąpi identycznie nazwane wpisy w archiwum zip lub doda pozycje dla nowych nazw.

Więc po prostu użyj zippolecenia tak, jak zwykle tworzysz nowy plik .zip zawierający tylko ten jeden plik, z wyjątkiem tego, że określona nazwa pliku .zip będzie istniejącym archiwum.

Proszę wstać
źródło
5
Czy ktoś mógłby podać przykład? Nie rozumiem pomocy polecenia zip.
Gustave
12
Powiedzmy, że zip -r myfolder.zip myfoldermyfolder/otherfolder/myfile.txtzip -r myfolder.zip myfolder/otherfolder/myfile.txt
spakowałeś mójfolder
1
Jak to zrobić, jeśli plik do zastąpienia nie ma takiej samej nazwy ani takiej samej struktury, jak plik do wymiany?
Fractaliste
2
@Fractaliste Musisz nadać mu tę samą nazwę i strukturę;)
Hack5
72

Zauważyłem, że zipplik Linuksa jest kłopotliwy przy zastępowaniu pojedynczego pliku w zipie. jarNarzędzie z pakietu Java Development Kit może być prostsze. Rozważ typowe zadanie aktualizacji WEB/web.xmlw pliku JAR (który jest zwykłym plikiem ZIP):

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

Tutaj path/to/dirjest ścieżka do katalogu zawierającego WEB-INFkatalog (który z kolei zawiera web.xml).

cayhorstmann
źródło
co jeśli będę musiał skopiować tylko plik zamiast tworzyć reżysera, WEB-INFktóry ma ten plik.
Pomocna dłoń
Również w moim przypadku, stary, drogi użytek „słoik” załatwił sprawę! Dzięki!
bitfox
51

Spróbuj wykonać następujące czynności:

zip [zipfile] [file to update] 

Przykład:

$ zip test.zip test/test.txt
updating: test/test.txt (stored 0%)
WizardsOfWor
źródło
2
Najłatwiej to zrozumieć dzięki przykładowi, dzięki!
vatsug
2
Weź pod uwagę, że updating:zamiast tego powinieneś zobaczyć, adding:jeśli chcesz zaktualizować plik wewnątrz zip; w przeciwnym razie dodajesz pliki do pliku ZIP, a nie go zastępujesz.
Edenshaw,
Masz rację, nie zauważyłem tego. Zaktualizowano, dzięki!
WizardsOfWor
13

Wiem, że to stare pytanie, ale chciałem zrobić to samo. Zaktualizuj plik w archiwum zip. Żadna z powyższych odpowiedzi nie pomogła mi.

Oto co zrobiłem. Utworzono katalog tymczasowy abc. Kopiowane file.zipdo abci wyjął plik w tym katalogu. Edytowałem plik, który chciałem edytować. Następnie będąc w abcśrodku, uruchom następujące polecenie

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

-u przełącznik będzie szukał zmienionych / nowych plików i doda je do archiwum zip.

tradycyjny
źródło
11

Użyj flagi aktualizacji: -u

Przykład:

zip -ur existing.zip myFolder

To polecenie skompresuje i doda myFolder(wraz z zawartością) do pliku existing.zip.


Użycie zaawansowane:

Flaga aktualizacji faktycznie porównuje przychodzące pliki z istniejącymi i albo doda nowe pliki, albo zaktualizuje istniejące.

Dlatego jeśli chcesz dodać / zaktualizować określony podkatalog w pliku zip, po prostu zaktualizuj źródło zgodnie z potrzebami, a następnie ponownie spakuj całe źródło z -uflagą. Tylko zmienione pliki zostaną spakowane.

Jeśli nie masz dostępu do plików źródłowych, możesz rozpakować plik zip, zaktualizować żądane pliki, a następnie ponownie spakować je z -uflagą. Ponownie, tylko zmienione pliki zostaną spakowane.

Przykład:

Oryginalna struktura źródła


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

Zaktualizowana struktura źródła


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

Stosowanie

$ zip -ur existing.zip ParentDir 
> updating: ParentDir/ChildDir/Logs (stored 0%)
>   adding: ParentDir/ChildDir/Logs/logs4.txt (stored 96%)
Ethan Strider
źródło
5

Możesz użyć: zip -u plik.zip ścieżka / plik_do_aktualizacji

Renato Luiz Ramos
źródło
1

Istnieje również opcja -f, która odświeży plik zip. Można go użyć do aktualizacji WSZYSTKICH plików, które zostały zaktualizowane od czasu wygenerowania pliku zip (zakładając, że znajdują się w tym samym miejscu w strukturze drzewa w pliku zip).

Jeśli twój plik ma nazwę /myfiles/myzip.zip, wszystko co musisz zrobić to

zip -f /myfiles/myzip.zip
gvrocha
źródło
0

Od strony struktury archiwum ZIP - możesz zaktualizować plik zip bez jego ponownego kompresowania, wystarczy pominąć wszystkie pliki, które są wcześniejsze od pliku, który chcesz zastąpić, a następnie umieścić zaktualizowany plik, a następnie resztę plików. I na koniec musisz umieścić zaktualizowaną centralną strukturę katalogów. Wątpię jednak, czy większość popularnych narzędzi pozwoliłaby Ci to zrobić.

Nickolay Olshevsky
źródło
0

7zip (7za) można wykorzystać do ładnego dodawania / aktualizowania plików / katalogów:

Przykład: Zastąpienie (niezależnie od daty pliku) MANIFEST.MFpliku w pliku JAR. /source/META-INFKatalog zawiera MANIFEST.MFplik, który chcesz umieścić w jar(ZIP):

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

Tylko aktualizacja (nie zastępuje celu, jeśli źródło jest starsze)

7za u /tmp/file.jar /source/META-INF/
mzsolt
źródło
-2

tak, to możliwe.

w systemach opartych na Linuksie po prostu zainstaluj zip i możesz go wywołać w linii poleceń. spójrz na stronę podręcznika: http://linux.die.net/man/1/zip

ale z mojego osobistego doświadczenia wynika, że ​​jeśli to możliwe, a kompresja nie jest tak ważna, działa to lepiej w przypadku zwykłych plików tar i tar.

Surrican
źródło