Por que o caractere curinga * é tão diferente entre os comandos zip e rm?

Por que o caractere curinga * é tão diferente entre os comandos zip e rm?

Elaborei um script para fazer algumas operações de arquivo para mim. Estou usando o operador curinga *para aplicar funções a todos os arquivos de um tipo, mas há uma coisa que não entendo. Posso unziptodos os arquivos em uma pasta como esta

unzip "*".zip

No entanto, para remover todos os arquivos zip posteriormente, preciso fazer

rm *.zip

Ou seja, não quer as aspas. A descompactação, por outro lado, não funciona se eu apenas der * (me dá um aviso de que "os arquivos não foram correspondidos").

Por que isso é diferente? Para mim, isso parece exatamente a mesma operação. Ou estou usando o curinga incorretamente?

Apresentações ao curingano Unix realmente não entramos nisso e não consegui localizar nada nos documentos rmou zip.

Estou usando o terminal em um Mac (Yosemite).

Responder1

Você explicou muito bem a situação. A peça final do quebra-cabeça é que unzipela mesma pode lidar com curingas:

http://www.info-zip.org/mans/unzip.html

ARGUMENTOS

arquivo[.zip]

...

Expressões curinga são semelhantes àquelas suportadas em shells Unix comumente usados ​​(sh, ksh, csh) e podem conter:

* corresponde a uma sequência de 0 ou mais caracteres

Ao citar o curinga *, você evitou que seu shell o expandisse, de modo que ele unzipvê o curinga e trata de expandi-lo de acordo com sua própria lógica.

rm, por outro lado, não suporta curingassozinho, portanto, tentar citar um curinga instruirá rma procurar um asterisco literal no nome do arquivo.

A razão pela qual unzip *.zipisso não funciona é que unzipa sintaxe do simplesmente não permite vários arquivos zip; se houver vários parâmetros, ele espera que o segundo e os subsequentes sejam arquivos no arquivo:

descompacte [-Z] [-cflptTuvz[abjnoqsCDKLMUVWX$/:^]] arquivo[.zip] [arquivo(s) ...] [-x xarquivo(s) ...] [-d exdir]

Responder2

A diferença entre esses dois comandos é o *caractere entre aspas. Se você chamar um comando em um shell e usar o *caractere como argumento, o próprio shell avaliará o argumento. Veja este exemplo:

$ ls
file1.zip  file2.zip  file3.zip  file4.txt

Agora com um *:

$ ls *.zip
file1.zip  file2.zip  file3.zip

O shell avalia o curinga e cria um comando da seguinte forma:

$ ls file1.zip  file2.zip  file3.zip

Com um curinga entre aspas, ele é interpretado como um arquivo chamado (literalmente) *.zip:

$ ls "*".zip
ls: cannot access *.zip: No such file or directory

O unziputilitário não pode ser chamado com vários arquivos compactados como argumentos. Mas, o desenvolvedor escolheu outra forma para isso. Na página de manual:

arquivo[.zip]

[...] As expressões curinga são semelhantes àquelas suportadas em shells Unix comumente usados ​​​​(sh, ksh, csh) [...] (Certifique-se de citar qualquer caractere que possa ser interpretado ou modificado pelo sistema operacional, particularmente em Unix e VMS.)

Responder3

A diferença é que no primeiro caso o próprio shell expande o globo:

% cd /                                                       
% echo *
Applications Library Network System Users Volumes bin cores ...
% 

enquanto no segundo caso o próprio aplicativo faz algo™ com esse caractere literal:

% cd /
% perl -E 'chdir "/tmp" or die; say for glob($ARGV[0])' "*"
com.apple.launchd.aj4FEhYqm5
...

Se não estiver entre aspas, o shell primeiro expande o globo, e o comando será executado com qualquer que seja o globo do shell expandido.

Responder4

As aspas são necessárias devido à maneira como o zip lida com vários argumentos:

rm: remova todos os arquivos da lista de argumentos

zip: descompacte o arquivo no primeiro argumento. extraia apenas os arquivos nos argumentos restantes.

$ 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

como você pode ver, ele tenta encontrar o arquivo2.zip e o arquivo3.zip dentro do arquivo1.zip

para permitir a extração de vários arquivos zip de uma vez, o zip suporta a interpretação do glob por si só, com um resultado diferente.

informação relacionada