Arme un script para hacer algunas operaciones de archivo por mí. Estoy usando el operador comodín *
para aplicar funciones a todos los archivos de un tipo, pero hay una cosa que no entiendo. Puedo unzip
todos los archivos en una carpeta como esta
unzip "*".zip
Sin embargo, para eliminar todos los archivos zip después, necesito hacer
rm *.zip
Es decir, no quiere las comillas. El descomprimir, por otro lado, no funciona si solo le doy el * (me da una advertencia de que "los archivos no coinciden").
¿Por qué es esto diferente? Para mí, esto parece exactamente la misma operación. ¿O estoy usando el comodín incorrectamente?
Las introducciones al comodín en Unix realmente no entran en esto, y no pude encontrar nada en los documentos rm
o zip
.
Estoy usando la terminal en una Mac (Yosemite).
unzip
podría hacer esto sin elfor f in *.zip;do...done
bucle de shell normal . Una interfaz de usuario de línea de comandos no similar a Unix tan extraña.unzip
aplica el glob al contenido de un archivo; no puedes obtenerlos de bash con un comodín. (Necesitarías `` para f inunzip -l archive.zip
; do ... done`)unzip
aceptar globos para que coincidan dentro de un único archivo zip. Pero esto es diferente; Realmente intentéunzip '*.zip'
en un directorio con múltiples archivos zip, y extrae todos los archivos de todos los zip. Como dije, súper raro.tar
no tiene ningún modo de operación como ese.Respuestas:
Has explicado muy bien la situación. La pieza final del rompecabezas es que
unzip
puede manejar comodines:http://www.info-zip.org/mans/unzip.html
Al citar el comodín *, evitó que su shell lo expandiera, por lo que
unzip
ve el comodín y trata de expandirlo de acuerdo con su propia lógica.rm
, por el contrario, no admite comodines por sí solo , por lo que intentar citar un comodín le indicarárm
que busque un asterisco literal en el nombre del archivo.La razón por la que
unzip *.zip
no funciona es queunzip
la sintaxis simplemente no permite múltiples archivos zip; Si hay varios parámetros, se espera que el segundo y los siguientes sean archivos en el archivo:fuente
unzip
el idioma propio, en el otro caso, la jerga general de Unix?for f in *.zip ; do unzip -v "$f" ; done
. y una gran parte de la razón por la cual el shell hace la expansión del nombre de archivo, etc., es en sí misma que cada programa individual no tiene que hacerlo (lo que resultaría en tener muchas implementaciones de expansión de comodines escritas independientemente que diferían en formas pequeñas pero molestas) .La diferencia entre esos dos comandos es el
*
carácter entre comillas . Si llama a un comando en un shell y usa el*
carácter para un argumento, el shell evaluará el argumento. Ver este ejemplo:Ahora con un
*
:El shell evalúa el comodín y crea un comando de la siguiente manera:
Con un comodín entre comillas, se interpreta como un archivo llamado (literalmente)
*.zip
:La
unzip
utilidad no puede ser llamada con múltiples archivos comprimidos como argumentos. Pero, el desarrollador eligió otra forma para esto. Desde la página del manual:fuente
unzip
eligieron seguir esa ruta, en lugar de permitir múltiples archivos comprimidos como argumentos?La diferencia está en el primer caso, el propio shell expande el globo:
mientras que en el segundo caso, la aplicación en sí hace Something ™ con ese carácter literal:
Si no se cita, el shell primero expande el glob, y el comando se ejecutará con lo que ese glob del shell se haya expandido.
fuente
Un comando recibirá los argumentos después de que el shell los haya procesado.
En el primer procesamiento, un
*
shell sin comillas se expandirá (a la lista de archivos en el directorio actual (pwd) que coinciden con el patrón):Listará todos los
.zip
archivos. Pero no loecho "*".zip"
hará .En el primer procesamiento, una cita
"*"
no se expandirá, se le dará al comando descomprimir como parámetro (después de que se haya eliminado la cita). El comando descomprimir recibirá un parámetro de*.zip
:Es el comando descomprimir que expande el
*
a la lista de archivos.También es interesante que estos dos comandos no realicen exactamente la misma acción final, y quién expande los
*
cambios:El primer comando recibe uno
*.zip
que se expande para procesar todos los archivos. El segundo comandounzip
recibirá una lista de todos los.zip
archivos en el pwd, que no procesará, ya que el desarrollador de descompresión ha elegido rechazar la expansión de más de unzip
archivo.fuente
Las comillas son necesarias debido a la forma en que zip maneja múltiples argumentos:
rm
: eliminar todos los archivos en la lista de argumentoszip
: descomprime el archivo en el primer argumento. solo extraiga los archivos en los argumentos restantes.como puede ver, intenta encontrar file2.zip y file3.zip dentro de file1.zip
Con el fin de permitirle extraer múltiples archivos zip a la vez, zip admite la interpretación del globo por sí mismo, con un resultado diferente.
fuente