J'ai mis en place un script pour faire quelques opérations de fichier pour moi. J'utilise l'opérateur générique *
pour appliquer des fonctions à tous les fichiers d'un type, mais il y a une chose que je ne comprends pas. Je peux unzip
tous les fichiers dans un dossier comme celui-ci
unzip "*".zip
Cependant, pour supprimer tous les fichiers zip par la suite, je dois faire
rm *.zip
Autrement dit, il ne veut pas les guillemets. La décompression, en revanche, ne fonctionne pas si je lui donne simplement le * (me prévient que "les fichiers ne correspondent pas").
Pourquoi est-ce différent? Pour moi, cela semble être exactement la même opération. Ou est-ce que j'utilise mal le joker?
Les introductions à la wildcard dans Unix n'entrent pas vraiment dans cela, et je ne pouvais rien localiser dans la documentation rm
ou zip
.
J'utilise le terminal sur un Mac (Yosemite).
unzip
je pouvais le faire sans lafor f in *.zip;do...done
boucle de shell normale . Une interface utilisateur en ligne de commande aussi étrange que celle de type Unix.unzip
applique le glob au contenu d'une archive; vous ne pouvez pas les obtenir de bash avec un joker. (Vous auriez besoin de `` `` pour le f inunzip -l archive.zip
; do ... done`)unzip
accepter les globs pour correspondre dans un fichier zip unique. Mais c'est différent. J'ai effectivement essayéunzip '*.zip'
dans un répertoire avec plusieurs fichiers zip, et il extrait tous les fichiers de tous les zips. Comme je le disais, super-bizarre.tar
n'a pas de mode de fonctionnement comme ça.Réponses:
Vous avez très bien expliqué la situation. La dernière pièce du puzzle est qu'il
unzip
peut gérer les caractères génériques lui-même:http://www.info-zip.org/mans/unzip.html
En citant le caractère générique *, vous avez empêché votre shell de l’étendre, ce qui permet de
unzip
voir le caractère générique et de l’agrandir selon sa propre logique.rm
, En revanche, ne supporte pas les caractères génériques sur son propre , afin de tenter de citer un caractère générique ordonnerarm
à la recherche d'un astérisque littéral dans le nom du fichier à la place.La raison pour laquelle cela
unzip *.zip
ne fonctionne pas est que saunzip
syntaxe ne permet tout simplement pas plusieurs fichiers zip; s'il y a plusieurs paramètres, il s'attend à ce que le deuxième et les suivants soient des fichiers dans l'archive:la source
unzip
propre langue, dans l’autre, le jargon général Unix?for f in *.zip ; do unzip -v "$f" ; done
. et une grande partie de la raison pour laquelle le shell effectue l’extension de nom de fichier, etc. en soi, est que chaque programme individuel n’a pas à le faire (ce qui entraînerait de nombreuses implémentations écrites indépendamment de l’expansion de caractères génériques qui différaient de manière petite mais ennuyeuse) .La différence entre ces deux commandes est le
*
caractère cité . Si vous appelez une commande dans un shell et utilisez le*
caractère comme argument, le shell lui-même évaluera l'argument. Voir cet exemple:Maintenant avec un
*
:Le shell évalue le caractère générique et construit une commande comme suit:
Avec un caractère générique cité, il est interprété comme un fichier nommé (littéralement)
*.zip
:L'
unzip
utilitaire ne peut pas être appelé avec plusieurs fichiers compressés comme arguments. Mais, le développeur a choisi un autre moyen pour cela. De la page de manuel:la source
unzip
choisi d'emprunter cette voie plutôt que de permettre plusieurs fichiers compressés comme arguments?La différence est dans le premier cas le shell lui-même développe le glob:
Dans le second cas, l'application elle-même Does Something ™ avec ce caractère littéral:
Si elle n'est pas citée, le shell étend d'abord le glob, et la commande sera exécutée avec le résultat étendu.
la source
Une commande recevra les arguments après leur traitement par le shell.
Lors du premier traitement, un shell
*
sera ajouté par le shell (à la liste des fichiers du répertoire present (pwd) qui correspondent au modèle):Va lister tous les
.zip
fichiers. Mais neecho "*".zip"
sera pas .Lors du premier traitement, une citation
"*"
ne sera pas développée, elle sera donnée à la commande unzip en tant que paramètre (une fois la citation supprimée). La commande unzip recevra un paramètre de*.zip
:C'est la commande unzip qui permet d'étendre le
*
à la liste des fichiers.Il est également intéressant de noter que ces deux commandes ne réaliseront pas exactement la même action finale, et qui étend les
*
modifications:La première commande reçoit un
*.zip
fichier qu’elle développe pour traiter tous les fichiers. La deuxième commandeunzip
recevra une liste de tous les.zip
fichiers du fichier pwd, qu’elle ne traitera pas, car le développeur décompacté a choisi de rejeter le développement de plusieurszip
fichiers.la source
Les guillemets sont nécessaires en raison de la façon dont zip gère plusieurs arguments:
rm
: supprimer tous les fichiers de la liste d'argumentszip
: décompressez le fichier dans le premier argument. extraire uniquement les fichiers dans les arguments restants.comme vous pouvez le voir, il essaie de trouver file2.zip et file3.zip dans file1.zip
afin de vous permettre d'extraire plusieurs fichiers zip à la fois, zip prend en charge l'interprétation du glob par lui-même, avec un résultat différent.
la source