Warum ist das Platzhalterzeichen * zwischen den Befehlen „Zip“ und „RM“ so unterschiedlich?

Warum ist das Platzhalterzeichen * zwischen den Befehlen „Zip“ und „RM“ so unterschiedlich?

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 unzipalle 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 Wildcardrmunter 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 unzipselbst 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 unziperkennt den Platzhalter und erweitert ihn entsprechend ihrer eigenen Logik.

rmunterstützt dagegen keine Platzhaltervon allein, daher führt der Versuch, ein Platzhalterzeichen in Anführungszeichen zu setzen, rmdazu, stattdessen nach einem wörtlichen Sternchen im Dateinamen zu suchen.

Das unzip *.zipfunktioniert nicht, weil unzipdie 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 unzipDienstprogramm 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.

verwandte Informationen