Gibt es eine Möglichkeit, alle Dateien in einem bestimmten Verzeichnis mit dem Befehl zip
zu komprimieren? Ich habe von der Verwendung von *.*
gehört, möchte aber, dass es auch für Dateien ohne Erweiterung funktioniert.
Kommentare
- Haben Sie versucht, von Ihrem gewünschten Verzeichnis aus eine Ebene nach oben zu navigieren und
zip myarch.zip mydir/*
auszuführen? - oder besser
zip -r myarch.zip mydir/*
- oder besser
zip -r myarch.zip mydir
-
*.*
bedeutet jede Datei mit einem Punkt cp / m und dos alle Dateien hatten einen Punkt, und Sie mussten ihn eingeben (*
konnte nicht ausgeführt werden). Daher kamen die Leute, um*.*
wie alle Dateien. Schließlich fügte Microsoft lange Dateinamen hinzu, die null oder mehr Punkte haben könnten. Um eine Datei mit einem Punkt in Windows zu finden, müssen Sie*.*.*
eingeben.
Antwort
Sie können einfach *
verwenden, es besteht keine Notwendigkeit für *.*
. Dateierweiterungen sind unter Unix nichts Besonderes. *
entspricht null oder mehr ch aracters – einschließlich eines Punktes. Es entspricht also foo.png
, da dies null oder mehr Zeichen sind (sieben, um genau zu sein).
Beachten Sie, dass *
stimmt standardmäßig nicht mit Dateien überein, die mit einem Punkt beginnen (*.*
). Das ist oft was du willst. Wenn nicht, wird in Bash, wenn Sie shopt -s dotglob
.
und..
). Andere Shells haben andere Möglichkeiten (oder gar keine), Punktedateien einzuschließen.
Alternativ hat zip
auch eine -r
(rekursive) Option, um ganze Verzeichnisbäume auf einmal zu erstellen (und sich nicht um das Dotfile-Problem kümmern zu müssen):
zip -r myfiles.zip mydir
wobei mydir
ist das Verzeichnis, das Ihre Dateien enthält. Beachten Sie, dass die erstellte Zip-Datei sowohl die Verzeichnisstruktur als auch die Dateien enthält. Wie Peterph in seinem Kommentar hervorhebt, wird dies normalerweise als eine gute Sache angesehen: Durch das Extrahieren der Zip werden alle extrahierten Dateien sauber in einem Unterverzeichnis gespeichert.
Sie können zip auch anweisen, die Pfade mit der nicht zu speichern -j
/ --junk-paths
Option.
Der Befehl zip
wird mitgeliefert Dokumentation, die Sie über alle (vielen) Optionen informiert; Geben Sie man zip
ein, um diese Dokumentation anzuzeigen. Dies ist nicht nur für zip möglich. Auf diese Weise können Sie die Dokumentation für die meisten Befehle abrufen.
Kommentare
- Möglicherweise möchten Sie hinzufügen, dass dies der Fall ist Es wird als gute Vorgehensweise angesehen, alles im Archiv in einem Verzeichnis der obersten Ebene zu speichern, damit ‚ sein aktuelles Verzeichnis beim Extrahieren nicht verschmutzt.
- @peterph erledigt. Obwohl dies in Zip-Dateien weniger eine Konvention ist als in z. B. Tarfiles, habe ich ‚ Angst.
- leider ja. Wahrscheinlich aufgrund der Fenster Erbe von Drag ‚ n ‚ Drop auf dem Desktop und Linux Erbe der Arbeit mit Quellcodes.
- Bleiben Sie drin Beachten Sie, dass
*
Shell-Globbing ‚ keine Punktedateien enthält (dh Dateinamen, die mit.
). Dies ist ein weiterer Vorteil beim Komprimieren des gesamten Verzeichnisses nach Namen. - Die Verwendung von -r umfasst jedoch das Verzeichnis selbst, wodurch das, was ich ‚ mache ich. Würde ‚ t * nicht
.
und..
enthalten?
?
Antwort
In meinem Fall wollte ich jede Datei in ein eigenes Archiv komprimieren, also habe ich Folgendes getan (in ):
$ for file in *; do zip ${file%.*}.zip $file; done
Kommentare
- Dort ‚ s no
mkv
hier? Auch hier ist nichts besonderszsh
-spezifisch. Sie ‚ möchten alle Variablen, die einen Dateinamen enthalten, korrekt in Anführungszeichen setzen, alsozip "${file%.*}.zip" "$file"
mit doppelten Anführungszeichen um beide Variablen. - @tripleee Zunächst einmal vielen Dank, dass Sie auf meinen fehlerhaften Verweis auf
mkv
hingewiesen haben. Zweitens ist das Zitieren von Argumenten inzsh
nicht erforderlich, im Gegensatz zubash
. Aus diesem Grund habe ich ‚ angegeben, dass dies ein Befehl fürzsh
ist. - Ersetzen des letzten Semikolons durch Ein kaufmännisches Und kann dies erheblich beschleunigen (wenn die Anzahl der Dateien im Verzeichnis angemessen ist …). Andernfalls
find . -type f -maxdepth 1 -print0|xargs -r0 -n1 -P64 -I{} bash -c 'f="{}"; zip "${f%.*}.zip" "$f"'
(wobei-P
abhängig von Ihren CPU-Threads angepasst wird …) (Viele GNU-Abhängigkeiten …) - Um jede Datei in ein eigenes Archiv zu komprimieren, führen Sie
gzip *
Antwort
aus
Eine andere Möglichkeit wäre die Verwendung von find und xargs: (Dies könnte ein „.“ – Verzeichnis in der Zip-Datei enthalten, sollte aber trotzdem korrekt extrahiert werden. Bei meinem Test hat zip den Punkt zuvor entfernt Komprimierung) find . -type f -exec zip zipfile.zip {} +
(Die +
kann durch \;
Wenn Ihre Version von find
das +
-Ende für exec nicht unterstützt. Es wird jedoch langsamer …)
Dies schließt standardmäßig alle Unterverzeichnisse ein. Auf GNU kann find -maxdepth
dies verhindern.
Kommentare
- (im Gegensatz zu den Lösungen mit
*
, dies schließt Punktdateien ein und ‚ fällt nicht um, wenn sich zu viele Dateien in einem Verzeichnis befinden)
Antwort
Eine andere (langsame) Methode, um dies zu tun (wobei jeweils eine Datei zur Zip hinzugefügt wird):
for f in * .[^.]*; do [ -r "$f" ] || continue # Skip directories or non-existant files (Probably ".[^.]*" if directory has no dotfiles). Using -e will allow directories to be used as well zip zipfile.zip "$f" # If directories are included, you probably want to add -r done
Dies hat die Dotfile-Probleme von *
(Problemumgehung hinzugefügt) und würde das Zip-Programm für jede Datei einmal starten und dem Archiv hinzufügen. In bash
würde es mit einer großen Anzahl von Dateien umgehen.
Es wäre langsamer als die meisten anderen Methoden, ist aber relativ einfach. P. >
Kommentare
- Ich würde sagen, dies ist weniger einfach als die akzeptierte Antwort und langsamer, was die Frage aufwirft: “ Warum sollte jemand das tun? „. Wenn Sie diese Frage beantworten können, empfehle ich Ihnen, diesen Kontext in Ihre Antwort aufzunehmen. Andernfalls halte ich es für eine schlechte Antwort auf eine alte Frage, die bereits eine gute Antwort hat.
- @Centimane: Ich stelle die Einschränkungen fest . Ich denke, das hat pädagogischen Wert. (Wenn Sie keine Verzeichnisse überspringen, ist dies ganz einfach). Wenn Sie stattdessen eine viel schnellere Antwort mit einem (Standard-) externen Tool wünschen, deckt meine andere Antwort dies ab. (Wenn die Behandlung mit Punktedateien entfernt wurde (was sich auf die Richtigkeit auswirkt, ohne dass sie in der Frage erwähnt werden), halte ich dies für recht elegant):
for f in *; do zip zip.zip "$f"; done
- Beachten Sie, dass die akzeptiert werden Die Antwort ‚ verwendet keinen externen Befehl und wäre schneller. In welchem Szenario wäre diese Antwort nützlich?
- @Centimane Mit tar, wenn mehr Dateien vorhanden sind, als Bash als Parameter übergeben kann. (find + xargs sind besser, denn Schleifen sind einfacher …). Es ist eine (einzigartige) Antwort auf die Frage. Es ist sicherlich nicht die optimale Antwort. (Nicht optimale Antworten können bei ähnlichen Problemen immer noch nützlich sein, wenn jemand eine etwas andere Situation hat – z. B. wenn er möchte, dass die Tar-Datei Verzeichnisse enthält)