você está aqui: Home  → Arquivo de Mensagens

Expansão de Chaves

Colaboração: Julio Cezar Neves

Data de Publicação: 28 de fevereiro de 2021

Ainda tem gente que pensa que o Shell é a mesma coisa que o DOS... Vejam só vocês! O que para nós do mundo do Software Livre é um interpretador, depois de estragado, decapitado e decepado, virou um sistema operacional que imperou desde o advento do PC até a era (r)windows.

Para ilustrar um pouco essas diferenças, mostrarei um mecanismo do Shell muito interessante, porém pouco conhecido e portanto pouco usado. Chama-se Expansão de Chaves ou Brace Expansion.

Expansão de chaves é um mecanismo pelo qual cadeias arbitrárias podem ser geradas. Este mecanismo é similar à expansão de nome de arquivos, porém os nomes de arquivos gerados não precisam existir.

A sintaxe de uma expansão de chaves é um abre chaves ({) seguido de valores separados por vírgula (,) e encerrados por um fecha chaves (}). Esta expressão poderá ser precedida ou seguida por outros valores e sua saída será na mesma ordem de entrada, isto é, não será classificada. Veja os exemplos:

$ echo a{x,y,z}b 
axb ayb azb
$ echo {B,F,M,C,P}ala 
Bala Fala Mala Cala Pala
$ echo ala{meda,mbique,rde} 
alameda alambique alarde
$ echo p{ata,ita,eitu}da 
patada pitada peituda

Você também pode construir uma expansão de chaves usando dois pontos (..) para dar uma idéia de sequência. Olha só isso:

$ echo {0..9} 
0 1 2 3 4 5 6 7 8 9
$ echo {9..0} 
9 8 7 6 5 4 3 2 1 0
$ echo {A..J} 
A B C D E F G H I J
$ echo {j..a} 
j i h g f e d c b a

Há algum tempo, estava fazendo uma palestra sobre Expressões Regulares e disse:

Para especificar uma lista para todas as letras do alfabeto (minúsculas e maiúsculas) usem sempre [A-Aa-z] e nunca [A-z] pois entre o Z e o a existem diversos caracteres, vejam:

$ echo {Z..a} 
Z [  ] ^ _ ` a

Bem, a esta altura do campeonato, você deve estar se perguntado:

— E pra quê serve isso?

Bem, quem trabalha com a cabeça não trabalha com o braço. Assim, ao invéz de fazer:

$ mkdir /usr/local/data
$ mkdir /usr/local/bin
$ mkdir /usr/local/var

Você pode simplesmente fazer:

$ mkdir /usr/local/{data,bin,var}

Ou complicando mais um pouquinho e usando expansão de arquivos:

$ chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}} 

Bem, frequentemente sou obrigado a gerar um arquivo para fazer testes em alguns comandos. Veja como faço isso rapidinho:

$ echo -e "\nLinha "{1..12} > arq.teste 
$ cat arq .teste
Linha 1 
Linha 2 
Linha 3 
Linha 4 
Linha 5 
Linha 6 
Linha 7 
Linha 8 
Linha 9 
Linha 10 
Linha 11 
Linha 12 

Vamos complicar um pouquinho para pegar todos os binários entre 0 e 15:

$ A={0,1}
$ eval echo $A$A$A$A
0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111

Um último exemplo e um desafio:

$ a={a,c,s} 
$ eval echo $a$a$a$a 

aaaa aaac aaas aaca aacc aacs aasa aasc aass acaa acac acas acca accc accs acsa acsc acss asaa asac asas asca ascc ascs assa assc asss caaa caac caas caca cacc cacs casa casc cass ccaa ccac ccas ccca cccc cccs ccsa ccsc ccss csaa csac csas csca cscc cscs cssa cssc csss saaa saac saas saca sacc sacs sasa sasc sass scaa scac scas scca sccc sccs scsa scsc scss ssaa ssac ssas ssca sscc sscs sssa sssc ssss

Repare que as instruções acima geraram todas as palavras de quatro letras, possíveis de escrever com as letras c, a e s. Repare ainda que coloquei em negrito as palavras válidas na língua portuguesa (válidas pelo menos para mim) ;). O dicionário ispell que existe em modo texto, pode filtrar a saída do comando, deixando somente as válidas.

O desafio é o seguinte: pago o chope para aquele que mandar para o meu e-mail (<educacao (a) dicas-l com br>) um scriptzinho para resolver logomania. Logomania é um jogo que aparece diariamente em um monte de jornais, onde te dão algumas letras e vence quem fizer o maior número de palavras válidas com aquelas letras.



Veja a relação completa dos artigos de Julio Cezar Neves