Ich habe ein Skript zusammengestellt, das einige Dateioperationen für mich durchführt. Ich verwende den Platzhalteroperator, *
um Funktionen auf alle Dateien eines Typs anzuwenden, aber es gibt eine Sache, die ich nicht verstehe. Ich kann unzip
alle Dateien in einem Ordner wie folgt
unzip "*".zip
Um jedoch anschließend alle Zip-Dateien zu entfernen, muss ich Folgendes tun:
rm *.zip
Das heißt, es will keine Anführungszeichen. Das Entpacken hingegen funktioniert nicht, wenn ich nur das * angebe (es gibt mir eine Warnung, dass „Dateien nicht übereinstimmen“).
Warum ist das anders? Für mich sieht das wie genau dieselbe Operation aus. Oder verwende ich das Platzhalterzeichen falsch?
Einführungen zur Wildcardrm
unter Unix gehen wir hierauf nicht näher ein und ich konnte in den Dokumenten nichts finden zip
.
Ich verwende das Terminal auf einem Mac (Yosemite).
Antwort1
Sie haben die Situation sehr gut erklärt. Das letzte Puzzleteil ist, dass es unzip
selbst mit Platzhaltern umgehen kann:
http://www.info-zip.org/mans/unzip.html
ARGUMENTE
Datei[.zip]
...
Platzhalterausdrücke ähneln denen, die in häufig verwendeten Unix-Shells (sh, ksh, csh) unterstützt werden, und können Folgendes enthalten:
* entspricht einer Folge von 0 oder mehr Zeichen
Durch die Anführungszeichen des Platzhalters * verhindern Sie, dass Ihre Shell ihn erweitert. Diese unzip
erkennt den Platzhalter und erweitert ihn entsprechend ihrer eigenen Logik.
rm
unterstützt dagegen keine Platzhaltervon allein, daher führt der Versuch, ein Platzhalterzeichen in Anführungszeichen zu setzen, rm
dazu, stattdessen nach einem wörtlichen Sternchen im Dateinamen zu suchen.
Das unzip *.zip
funktioniert nicht, weil unzip
die Syntax von einfach nicht mehrere ZIP-Dateien zulässt. Wenn mehrere Parameter vorhanden sind, wird erwartet, dass es sich beim zweiten und den folgenden um Dateien im Archiv handelt:
unzip [-Z] [-cflptTuvz[abjnoqsCDKLMUVWX$/:^]] Datei[.zip] [Datei(en) ...] [-x xDatei(en) ...] [-d exdir]
Antwort2
Der Unterschied zwischen diesen beiden Befehlen ist das *
Anführungszeichen. Wenn Sie einen Befehl in einer Shell aufrufen und das *
Anführungszeichen als Argument verwenden, wertet die Shell das Argument selbst aus. Sehen Sie sich dieses Beispiel an:
$ ls
file1.zip file2.zip file3.zip file4.txt
Jetzt mit einem *
:
$ ls *.zip
file1.zip file2.zip file3.zip
Die Shell wertet das Platzhalterzeichen aus und erstellt einen Befehl wie folgt:
$ ls file1.zip file2.zip file3.zip
Mit einem Platzhalterzeichen in Anführungszeichen wird es als eine Datei mit dem (wörtlichen) Namen interpretiert *.zip
:
$ ls "*".zip
ls: cannot access *.zip: No such file or directory
Das unzip
Dienstprogramm kann nicht mit mehreren komprimierten Dateien als Argumente aufgerufen werden. Der Entwickler hat hierfür jedoch einen anderen Weg gewählt. Aus der Manpage:
Datei[.zip]
[...] Platzhalterausdrücke ähneln denen, die in häufig verwendeten Unix-Shells (sh, ksh, csh) unterstützt werden [...] (Stellen Sie sicher, dass Sie alle Zeichen in Anführungszeichen setzen, die sonst vom Betriebssystem interpretiert oder geändert werden könnten, insbesondere unter Unix und VMS.)
Antwort3
Der Unterschied besteht darin, dass im ersten Fall die Shell selbst den Glob erweitert:
% cd /
% echo *
Applications Library Network System Users Volumes bin cores ...
%
während im zweiten Fall die Anwendung selbst etwas mit diesem wörtlichen Zeichen tut:
% cd /
% perl -E 'chdir "/tmp" or die; say for glob($ARGV[0])' "*"
com.apple.launchd.aj4FEhYqm5
...
Wenn keine Anführungszeichen vorhanden sind, erweitert die Shell zuerst den Glob, und der Befehl wird mit dem ausgeführt, worauf der Shell-Glob erweitert wurde.
Antwort4
Die Anführungszeichen sind aufgrund der Art und Weise erforderlich, wie Zip mehrere Argumente verarbeitet:
rm
: Entfernt alle Dateien in der Argumentliste
zip
: Entpacken Sie die Datei im ersten Argument. Extrahieren Sie nur die Dateien in den verbleibenden Argumenten.
$ ls *.zip
file1.zip file2.zip file3.zip
$ unzip *.zip
Archive: file1.zip
caution: filename not matched: file2.zip
caution: filename not matched: file3.zip
wie Sie sehen, versucht es, file2.zip und file3.zip in file1.zip zu finden
Damit Sie mehrere ZIP-Dateien gleichzeitig extrahieren können, unterstützt Zip die eigenständige Interpretation des Globs mit unterschiedlichen Ergebnissen.