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.

Você vai aprender
  • 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 echo antes 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ãoCombina com
*.mp4Tudo 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
O * 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ãoCombina 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 fazProcura arquivos que existemGera palavras, existam ou não
Bom parals, cp, mv, rm em arquivos existentesCriar vários (mkdir, touch) e escrever menos
Se nada combinarO padrão passa como textoSempre 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:

  1. Escreva o padrão com echo: echo *.tmp.
  2. Leia a lista. É exatamente isso que você quer apagar?
  3. Aperte ↑ para trazer o comando de volta, troque echo por rm e rode.
Um espaço muda tudo

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

"não é possível acessar '*.mp3'"
$ 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.

"Lista de argumentos muito longa"
$ 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 curinga não pegou os arquivos ocultos

O que aconteceu: * ignora nomes que começam com ponto.

Como resolver: use também .*, como em ls -d .* *.


Referência

SímboloSignificadoExemplo
*Qualquer sequência de caracteres*.jpg
?Exatamente um caracterefoto?.jpg
[abc]Um caractere da listafoto[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ênciaaula{01..10}
**Esta pasta e todas as de dentro (com globstar)**/*.css
"…" ou '…'Desliga os curingasfind . -name "*.log"

Exercícios

1. Todos os PDFs

Complete para copiar todos os PDFs da pasta atual para ~/Documentos:

cp ~/Documentos/

2. Um caractere

Complete para listar cap1.md a cap9.md, mas não cap10.md:

ls cap.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ão mostra 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 rm ou mv com curinga: echo primeiro.