Eu montei 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. Eu posso unzip
todos os arquivos em uma pasta como esta
unzip "*".zip
No entanto, para remover todos os arquivos zip depois, preciso fazer
rm *.zip
Ou seja, ele não deseja aspas. O descompactação, por outro lado, não funciona se eu apenas der o * (me avisa 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?
Introduções para o wild card em Unix realmente não ir para este, e eu não conseguia localizar qualquer coisa no rm
ou zip
docs.
Estou usando o terminal em um Mac (Yosemite).
unzip
poderia fazer isso sem ofor f in *.zip;do...done
loop de shell normal . Uma interface de usuário de linha de comando estranha e não unix.unzip
aplica a glob ao conteúdo de um arquivo; você não pode obtê-los do bash com um curinga. (Você precisa de `` `for f inunzip -l archive.zip
; fazer ... done`)unzip
aceitar globs para combinar dentro de um único arquivo zip. Mas isso é diferente; Na verdade, eu tenteiunzip '*.zip'
em um diretório com vários arquivos zip e extrai todos os arquivos de todos os zips. Como eu disse, super estranho.tar
não possui nenhum modo de operação como esse.Respostas:
Você explicou a situação muito bem. A peça final do quebra-cabeça é que
unzip
pode lidar com curingas:http://www.info-zip.org/mans/unzip.html
Ao citar o curinga *, você impediu que seu shell o expandisse, para que ele
unzip
veja o curinga e lide com a expansão de acordo com sua própria lógica.rm
, por outro lado, não suporta curingas por si só , portanto, tentar citar um curinga instruirárm
a procurar um asterisco literal no nome do arquivo.O motivo que
unzip *.zip
não funciona é queunzip
a sintaxe simplesmente não permite vários arquivos zip; se houver vários parâmetros, espera que o segundo e os seguintes sejam arquivos no arquivo morto:fonte
unzip
o próprio idioma, no outro caso o jargão geral do unix?for f in *.zip ; do unzip -v "$f" ; done
. e uma grande parte da razão pela qual o shell faz a expansão do nome do arquivo etc é algo que não é necessário para cada programa individual (o que resultaria em muitas implementações de expansão de curinga escritas independentemente, que diferiam de maneiras pequenas, mas irritantes) .A diferença entre esses dois comandos é o
*
caractere citado . Se você chamar um comando em um shell e usar o*
caractere para um argumento, o próprio shell avaliará o argumento. Veja este exemplo:Agora com um
*
:O shell avalia o curinga e cria um comando da seguinte maneira:
Com um curinga entre aspas, ele é interpretado como um arquivo chamado (literalmente)
*.zip
:O
unzip
utilitário não pode ser chamado com vários arquivos compactados como argumentos. Mas, o desenvolvedor escolheu outro caminho para isso. Na página de manual:fonte
unzip
escolheram seguir esse caminho, em vez de permitir vários arquivos compactados como argumentos?A diferença é que, no primeiro caso, o próprio shell expande o globo:
enquanto no segundo caso, o próprio aplicativo Does Something ™ com esse caractere literal:
Se não estiver entre aspas, o shell primeiro expande a glob e o comando será executado com qualquer que seja a expansão da glob shell.
fonte
Um comando receberá os argumentos após serem processados pelo shell.
No primeiro processamento, um não citado
*
será expandido pelo shell (para a lista de arquivos no diretório atual (pwd) que correspondem ao padrão):Irá listar todos os
.zip
arquivos. Mas nãoecho "*".zip"
vai .No primeiro processamento, uma citação
"*"
não será expandida, será dada ao comando descompactar como parâmetro (após a remoção da citação). O comando descompactar receberá um parâmetro de*.zip
:É o comando descompactar que expande
*
para a lista de arquivos.Também é interessante que esses dois comandos não executem exatamente a mesma ação final e quem expanda as
*
alterações:O primeiro comando recebe um
*.zip
que se expande para processar todos os arquivos. O segundo comandounzip
receberá uma lista de todos os.zip
arquivos no pwd, que não serão processados, pois o desenvolvedor de descompactar optou por rejeitar a expansão de mais de umzip
arquivo.fonte
As aspas são necessárias devido à maneira como o zip lida com vários argumentos:
rm
: remova todos os arquivos na lista de argumentoszip
: descompacte o arquivo no primeiro argumento. extraia apenas os arquivos nos argumentos restantes.como você pode ver, ele tenta encontrar file2.zip e file3.zip dentro de file1.zip
para permitir que você extraia vários arquivos zip de uma só vez, o zip suporta a interpretação do glob por si só, com um resultado diferente.
fonte