zip file aufteilen mit unix/linux

Software besorgen und anwenden
Post Reply
Message
Author
John
Posts: 1
Joined: 19. Jun 2006 14:24

zip file aufteilen mit unix/linux

#1 Post by John »

Hallo,

ich habe eine Frage: Ich muss eine größere Datenmenge (ca. 10.000) auf mehrere ZIP-Files aufteilen. Gibt es da unter unix einen schnellen Weg mit zip? d.h. einen Befehl mit dem alle files in einem Verzeichnis gezippt werden und zwar in 500 Blöcken? Für Hilfe wäre ich sehr sehr dankbar.

Beste Grüße
Markus

User avatar
jochen
prolinux-forum-admin
Posts: 699
Joined: 14. Jan 2000 15:37
Location: Jülich
Contact:

#2 Post by jochen »

Hi,

ein festes Kommando dazu gibt es nicht, aber man kann mittels awk schnell ein kleines Skriptchen dazu schreiben:

Code: Select all

#!/bin/bash

ls | awk '
BEGIN {
        zipfilenum = 1
        zipfilebasename = "data"
        zipformat="%s%03d.zip"
        zipfile = sprintf (zipformat, zipfilebasename, zipfilenum)
        zipcommandbase = "zip -q -@ "
        zipcommand = zipcommandbase zipfile
}

{
        print $0 | zipcommand
        if (0 == NR % 500) {
                close (zipcommand)
                zipfilenum++
                zipfile = sprintf (zipformat, zipfilebasename, zipfilenum)
                zipcommand = zipcommandbase zipfile
        }
}'
Im BEGIN-Fall werden nur ein paar Variablen vordefiniert; hier kannst Du den Stammnamen der Archive u.ä. ändern. Ansonsten listet ls alle Dateien auf, die alle in das von stdin lesende zip-Kommando gepipet werden. Wenn wieder 500 Dateien komplett verarztet wurden, wird das Kommando beendet und damit das Zip-Archiv geschlossen und für die nächsten 500 Dateien das neue Kommando generiert.

War's das, was Du suchtest?

Jochen
Die grösste Lüge der EDV? "Mal eben..."

Gast

#3 Post by Gast »

Das dürfte nicht funktionieren:

Code: Select all

...
{ 
        print $0 | zipcommand 
        if (0 == NR % 500) { 
                close (zipcommand) 
                zipfilenum++ 
                zipfile = sprintf (zipformat, zipfilebasename, zipfilenum) 
                zipcommand = zipcommandbase zipfile 
        } 
}
Während awk über alle Parameter mit print iteriert, bleibt die Ausgabe wohl offen (bin kein awk-Kenner) und "zip -q -@ " bekommt alles als einen String. Da zip beim "lesen aus Eingabestrom" wohl ein NL (oder/und CR?) als Recordseparator interpretiert, könnte printf( "%s\n", $0 ) | zipcommand eine brauchbare aber unsaubere, nicht allgemeingültige Lösung sein. Eine solche wird es zusammen mit zip so aber auch nicht geben, denn wenn ein Dateiname ein CR/NL enthält, funktioniert es eben nicht mehr.

############

Zu Ausgangsfrage: Hätte eher aufteilen des Daten-Volumens (multi-volume archive) vermutet, obwohl die Formulierung ... größere Datenmenge (ca. 10.000) ... Jochens Stückzahl-Interpretation näher legt.

MfG
Gast

User avatar
jochen
prolinux-forum-admin
Posts: 699
Joined: 14. Jan 2000 15:37
Location: Jülich
Contact:

#4 Post by jochen »

Das dürfte nicht funktionieren:
Mal ausprobiert? Ich habe das Skript funktionierend mittels Copy'n'Paste übernommen... Aber ich gebe gerne zu, dass es bei Dateinamen mit Newlines Probleme geben kann.
Während awk über alle Parameter mit print iteriert
?!? $0 enthält die Eingabezeile, also einen Dateinamen. Nach jedem print erfolgt ein Newline, also werden die Dateinamen zeilenweise an zip übergeben. Enthält ein Dateiname ein Newline, interpretiert der awk diesen bereits als zwei unterschiedliche Eingabezeilen; das Problem ist also grundsätzlicher Art. Selbst wenn man sich mit "find ... -print0" und "RS="\0" Mühe gibt, trifft letzten Endes Dein Kommentar, dass zip damit Schwierigkeiten hätte.

Jochen
Die grösste Lüge der EDV? "Mal eben..."

komsomolze
Posts: 430
Joined: 03. Mar 2006 23:16

#5 Post by komsomolze »

Code: Select all

zipsplit
?

Gast

#6 Post by Gast »

Komsomolze,
ja, zipsplit u.ä., aber John lies ja nichts mehr verlauten.

Jochen, awk
Hast Du recht, ein einfaches print packt ein NL mit 'ran. Asche auf meine Glatze. Habe gerade praktische awk-Erfahrung gesammelt. Bin eben kein awk-Kenner und habe mich von Perl-print oder C-printf leiten lassen. Awk-print entpricht halt C-puts.
Jo, bin noch lernfähig finde vielleicht gar Freude an awk, aber wenn mir Jochen hierfür kein Heilmittel nennen kann:
» ... Enthält ein Dateiname ein Newline, interpretiert der awk diesen bereits als zwei unterschiedliche Eingabezeilen ... «
wird nicht all zu viel mit Freude. Klar ein NL ist nun mal ein (Eingabe-)Zeilentrenner, aber Du weißt schon, was ich meine.

Ist ein recht allgemeines Ärgernis mit quoten, escapen, Zeichensätzen ...
Dateidialoge (irgendwelcher Toolkits) steigen aus, wenn sie mit den Zeichensätzen nicht klar kommen, da ist es oft nicht mal möglich ein File zu öffnen, obwohl die angebotenen Zeichen nichts anderes als einfache Bytes sind und genau so (und nicht irgendwie missinterpretiert) an das System (fopen) zurückgereicht werden
brauchen.

####

ls | zip -@ daszipfile.zip
zip warning: name not matched: File mit
zip warning: name not matched: NL
adding: File_0 (stored 0%)
adding: File_1 (stored 0%)

ls hat ja die Option Q (Lob den Machern!), nur zip und die meisten anderen Programme können damit nichts anfangen.

ls -Q | zip -@ daszipfile.zip
zip warning: name not matched: "File mit \nNL"
zip warning: name not matched: "File_0"
zip warning: name not matched: "File_1"

komsomolze
Posts: 430
Joined: 03. Mar 2006 23:16

#7 Post by komsomolze »

Code: Select all

for i in * ; do echo $i ; done | zip -@ daszipfile.zip
oder
for i in * ; do echo \"$i\" ; done | zip -@ daszipfile.zip
?

Post Reply