Ubuntu Curingas
Curingas são símbolos que representam "qualquer coisa" num nome de arquivo. Com eles, *.jpg significa "todos os arquivos que terminam em .jpg". Eles funcionam com qualquer comando: ls, cp, mv, rm… Em inglês, o recurso se chama globbing.
- Os quatro símbolos:
*,?,[ ]e{ }. - Quem transforma o curinga em nomes: o shell, e não o comando.
- A diferença entre curingas (acham o que existe) e chaves (geram nomes novos).
- Como conferir com
echoantes de rodar algo perigoso.
A ideia: o shell troca o padrão pelos nomes
Quando você digita ls *.mp4, o ls nunca vê o asterisco. O shell (o bash, programa que lê o que você digita) procura os arquivos que combinam com o padrão e troca *.mp4 pela lista de nomes. Só depois ele chama o ls.
você digita: ls *.mp4 o shell troca: ls aula10.mp4 aula1.mp4 aula2.mp4 aula3.mp4 o ls recebe: 4 nomes de arquivo
O echo só repete o que recebe. Por isso ele é a melhor forma de ver em que um curinga vai virar:
$ ls Resumo-final.txt aula1.pdf aula2.mp4 aula3.mp4 resumo.txt aula1.mp4 aula10.mp4 aula2.pdf notas.TXT $ echo *.mp4 aula10.mp4 aula1.mp4 aula2.mp4 aula3.mp4 « os nomes que o comando vai receber
A ordem do echo é diferente da do ls: o shell ordena os nomes pelas regras do português (ignorando pontos e maiúsculas), e o ls do Ubuntu 26.04 ordena pelo código de cada caractere. O conteúdo é o mesmo.
*: qualquer coisa
O asterisco combina com qualquer sequência de caracteres, inclusive nenhuma.
| Padrão | Combina com |
|---|---|
*.mp4 | Tudo que termina em .mp4 |
aula* | Tudo que começa com aula |
*resumo* | Tudo que tem resumo em qualquer lugar do nome |
* | Todos os arquivos visíveis da pasta |
$ echo *.txt Resumo-final.txt resumo.txt $ ls -l aula1* -rw-rw-r-- 1 ana ana 0 Oct 15 10:30 aula1.mp4 -rw-rw-r-- 1 ana ana 0 Oct 15 10:30 aula1.pdf -rw-rw-r-- 1 ana ana 0 Oct 15 10:30 aula10.mp4
* não pega arquivos ocultos
Nomes que começam com ponto (.bashrc) ficam de fora de *. Para incluí-los, o padrão precisa começar com ponto: .*.
?: exatamente um caractere
O ponto de interrogação vale por um caractere, qualquer um. Dois ?? valem por dois.
$ echo aula?.mp4 aula1.mp4 aula2.mp4 aula3.mp4 « um caractere entre "aula" e ".mp4" $ echo aula??.mp4 aula10.mp4 « exatamente dois
[ ]: um caractere de uma lista
Os colchetes valem por um caractere, mas só os que estão listados dentro deles.
| Padrão | Combina com um caractere que seja… |
|---|---|
[12] | 1 ou 2 |
[0-9] | Qualquer dígito |
[a-z] / [A-Z] | Letra minúscula / maiúscula |
[!1] ou [^1] | Qualquer um, menos 1 |
[tT] | t ou T (útil contra maiúsculas) |
$ echo aula[12].* aula1.mp4 aula1.pdf aula2.mp4 aula2.pdf $ echo [A-Z]* Resumo-final.txt « só o que começa com maiúscula $ echo *.[tT][xX][tT] notas.TXT Resumo-final.txt resumo.txt « .txt em maiúsculas ou minúsculas
Missão: na pasta aulas, mova todos os vídeos .mp4 para a pasta videos com um único comando. Antes, confira o padrão com echo.
{ }: chaves geram nomes
As chaves parecem curinga, mas funcionam diferente. Elas geram uma lista de palavras, quer os arquivos existam ou não:
$ echo aula{1,2,3}.mp4
aula1.mp4 aula2.mp4 aula3.mp4
$ echo aula{4,5}.mp4
aula4.mp4 aula5.mp4 « esses arquivos nem existem
$ echo foto{01..03}.jpg
foto01.jpg foto02.jpg foto03.jpg
Curinga × chaves
Curinga (* ? [ ]) | Chaves ({ }) | |
|---|---|---|
| O que faz | Procura arquivos que existem | Gera palavras, existam ou não |
| Bom para | ls, cp, mv, rm em arquivos existentes | Criar vários (mkdir, touch) e escrever menos |
| Se nada combinar | O padrão passa como texto | Sempre gera as palavras |
$ ls aula{4,5}.mp4
ls: não é possível acessar 'aula4.mp4': Arquivo ou diretório inexistente
ls: não é possível acessar 'aula5.mp4': Arquivo ou diretório inexistente
$ mkdir modulo{1..3}
$ echo modulo*
modulo1 modulo2 modulo3
Os dois combinam bem: echo *.{mp4,pdf} pega todos os vídeos e PDFs.
Quando nada combina
Se nenhum arquivo combina, o bash passa o padrão como texto para o comando. O resultado depende do comando:
$ echo *.mkv *.mkv « nenhum .mkv: o padrão passou como texto $ ls *.mkv ls: não é possível acessar '*.mkv': Arquivo ou diretório inexistente
Para o ls, a mensagem parece estranha: ele procurou um arquivo chamado literalmente *.mkv. Agora você sabe por quê.
Aspas desligam os curingas
Entre aspas, *, ? e [ ] são caracteres comuns. Isso é necessário quando o comando, e não o shell, deve receber o padrão, como no find:
$ echo "*.mp4" *.mp4 $ find ~ -name "*.pdf"
Curingas em subpastas: **
O * não atravessa pastas: *.css só olha a pasta atual. Com a opção globstar ligada, ** significa "esta pasta e todas as de dentro":
$ echo **/*.css a/y.css « sem globstar, ** é igual a * $ shopt -s globstar $ echo **/*.css a/b/z.css a/y.css x.css « agora entra em todas as subpastas
Para ligar sempre, coloque shopt -s globstar no ~/.bashrc. A alternativa clássica é o find (veja find e locate).
A regra de ouro: echo antes de rm
Um curinga mal escrito pode pegar arquivos que você não queria. Antes de qualquer comando que apaga ou move, rode o mesmo padrão com echo ou ls:
- Escreva o padrão com
echo:echo *.tmp. - Leia a lista. É exatamente isso que você quer apagar?
- Aperte ↑ para trazer o comando de volta, troque
echoporrme rode.
rm *.tmp apaga os .tmp. rm * .tmp (com espaço) apaga todos os arquivos da pasta e depois tenta apagar um arquivo chamado .tmp. Confira sempre com echo.
Missão: na pasta limpeza, apague todos os arquivos .tmp e mais nada. Siga a regra de ouro: primeiro echo, depois rm.
Quando não funciona
$ ls *.mp3 ls: não é possível acessar '*.mp3': Arquivo ou diretório inexistente
O que aconteceu: nenhum arquivo combina com o padrão. Lembre que maiúsculas importam: *.mp3 não pega MUSICA.MP3.
Como resolver: confira com ls e, se precisar, use *.[mM][pP]3.
$ rm *.jpg bash: /usr/bin/rm: Lista de argumentos muito longa
O que aconteceu: o padrão virou centenas de milhares de nomes, mais do que o sistema aceita numa linha de comando.
Como resolver: deixe o find fazer o trabalho: find . -maxdepth 1 -name "*.jpg" -delete.
O que aconteceu: * ignora nomes que começam com ponto.
Como resolver: use também .*, como em ls -d .* *.
Referência
| Símbolo | Significado | Exemplo |
|---|---|---|
* | Qualquer sequência de caracteres | *.jpg |
? | Exatamente um caractere | foto?.jpg |
[abc] | Um caractere da lista | foto[123].jpg |
[a-z] | Um caractere do intervalo | [0-9]* |
[!abc] | Um caractere fora da lista | [!.]* |
{a,b} | Gera cada alternativa | {jan,fev}.txt |
{1..5} | Gera uma sequência | aula{01..10} |
** | Esta pasta e todas as de dentro (com globstar) | **/*.css |
"…" ou '…' | Desliga os curingas | find . -name "*.log" |
Exercícios
1. Todos os PDFs
Complete para copiar todos os PDFs da pasta atual para ~/Documentos:
2. Um caractere
Complete para listar cap1.md a cap9.md, mas não cap10.md:
3. Conferir antes
Qual comando você roda antes de rm *.bak para ver o que seria apagado, sem apagar nada?
4. Na pasta só existem a.txt e b.txt. O que echo {a,b,c}.txt mostra?
5. Quem transforma *.jpg na lista de arquivos?
Resumo
*= qualquer coisa;?= um caractere;[ ]= um caractere de uma lista.- Quem expande os curingas é o shell.
echo padrãomostra o resultado. - Chaves
{ }geram nomes que não precisam existir; curingas só acham os que existem. - Sem nenhum arquivo correspondente, o padrão passa como texto.
- Antes de
rmoumvcom curinga:echoprimeiro.