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 besonders zsh -spezifisch. Sie ‚ möchten alle Variablen, die einen Dateinamen enthalten, korrekt in Anführungszeichen setzen, also zip "${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 in zsh nicht erforderlich, im Gegensatz zu bash. Aus diesem Grund habe ich ‚ angegeben, dass dies ein Befehl für zsh 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)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.