Rezip-Datei, ohne temporäre Dateien zu erstellen

446
Hashbrown

Am besten fange ich einfach mit dem Use Case an.
Ich habe eine große ZIP-Datei mit vielen Dateien, und ich vermute, dass sie ursprünglich mit einer niedrigen Komprimierungsstufe komprimiert wurde.

Ich möchte eine neue ZIP-Datei erstellen (oder nicht neu, hoffentlich vor Ort), um sicherzustellen, dass sie gut komprimiert wird ( -9), ohne sie vorher auf die Festplatte zu entpacken (aus verschiedenen Gründen, z. B. Größe und angehängtes NFS). So konnte ich es einfach tun

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

Das wäre [vorübergehend] eine riesige Menge von Daten erstellen (die entpackten Dateien und B.zipin der Existenz kommen, bevor A.zipentfernt wird).
Ich möchte wirklich etwas in der Art von:

rezip -9 A.zip 

oder für einen Vergleich B.zip:

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

Ich weiß jedoch, dass dies möglicherweise nicht wirklich möglich ist, da die Pipe für mehrere Dateien verwendet wird und Dinge wie Dateinamen verloren gehen würden.

Ich frage mich also, ob es eine Möglichkeit gibt, Code für jede Datei auszuführen, wie z find -exec <command>

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

Unsicher, wie dies funktionieren würde, oder, falls dies nicht durch unzip/ erleichtert wird zip, ob es einen Befehl gibt, der dies tut.

Ich habe meine aktuellen, noch verarbeitbaren temporären Dateien einzelner Workarounds als Antwort hinzugefügt, da dies jemandem helfen könnte, auch wenn dies nicht akzeptiert wird, da es nicht die Frage beantwortet, ob keine temporären Dateien zulässig sind

0

1 Antwort auf die Frage

0
Hashbrown

Das ist so nahe wie ich konnte

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

Dabei wird immer nur eine tmp-Datei für jede Datei in der ZIP-Datei erstellt.
Wenn ich einen Weg finden kann, einen stdinDateinamen zu finden und zu übergeben, kann ich -pstattdessen Pipes verwenden.

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

Aber es ist schwierig