a[bc]dé um padrão de nome de arquivo (em shells diferentes de fish). Ele se expandirá para os dois nomes de arquivoabd e acdse esses forem nomes de arquivos existentes no diretório atual.
A [...]parte é uma expressão entre colchetes que corresponde a um único caractere dentre os listados (ou elementos de agrupamento quando os intervalos são incluídos). Para corresponder ao padrão a[bc]d, o caractere entre as strings ae dem um nome de arquivo deve ser a bou a c.
Se abdexistir, mas acdnão existir, então só se expandirá para abd, e vice-versa.
Se nem abd, nem acdexistir, dependendo do shell e das opções, ele acionaria um erro (original Unix sh, (t)csh, zsh, fish, bash -O failglob) e possivelmente sairia do shell, ou deixaria o padrão não expandido¹ (shells do tipo Bourne e rc-like) ou expandir para nada ( bash/zsh/yash -o nullglob, algumas versões mais antigas de fish, Unix original she (t)cshse houver outros globs correspondentes no mesmo comando).
a{b,c}dé uma expansão de chaves (em shells que os suportam). Ele se expandirá para as duas stringsabd e acd.
A {...}parte é um conjunto de strings delimitado por vírgulas (neste exemplo; em algum shell, também pode ser um intervalo como a..kou 20..25ou mais avançados como 00..20..2ou 0..20..2%02d), e a expansão é calculada combinando cada uma dessas strings com o flanqueamento cordas ae d. Essas strings podem ser maiores que um único caractere e também podem ser expansões de chaves.
A expansão acontece independentemente de essas strings corresponderem a nomes de arquivos existentes ou não.
Se você estiver construindo strings, use uma expansão de chaves. Se você estiver combinando nomes de arquivos, use um padrão de nome de arquivo.
¹ Neste caso em particular, a[bc]dpoderia ser o nome de um arquivo existente e é por isso que é potencialmente perigoso usar coisas como rm -f ./*.[ch]nesses shells e rm -f ./*.{c,h}é um problema menor.
a[bc]dé de correspondência de padrões e faz parte do padrão POSIX. No POSIX, isso é introduzido como a "expressão de colchetes de padrão". Está documentado na seção 2.13 do manual
Quando sem aspas e fora de uma expressão entre colchetes, os três caracteres a seguir terão significado especial na especificação de padrões:
?
Um ponto de interrogação é um padrão que deve corresponder a qualquer caractere.
*
Um asterisco é um padrão que deve corresponder a vários caracteres, conforme descrito em Padrões que correspondem a vários caracteres.
[
O colchete aberto deve introduzir uma expressão de colchete padrão.
A seção 2.13.3 também menciona algo que se comporta de maneira diferente do que se esperaria para regexs usuais quando é usado para expansão de nome de arquivo (ênfase minha)
As regras descritas até agora em Padrões que correspondem a um único caractere e Padrões que correspondem a vários caracteres são qualificadas pelas seguintes regras que se aplicam quando a notação de correspondência de padrões é usada para expansão de nome de arquivo:
O caractere de barra em um nome de caminho deve ser correspondido explicitamente usando uma ou mais barras no padrão; não deve ser correspondido pelos caracteres especiais asterisco ou ponto de interrogação nem por uma expressão de colchetes. As barras no padrão devem ser identificadas antes das expressões de colchetes; portanto, uma barra não pode ser incluída em uma expressão de colchete padrão usada para expansão de nome de arquivo. Se um caractere de barra for encontrado após um caractere de colchete aberto sem escape antes que um colchete de fechamento correspondente seja encontrado, o colchete deve ser tratado como um caractere comum. Por exemplo, o padrão
"a[b/c]d"não corresponde a nomes de caminho como abdou a/d. Ele corresponde apenas a um nome de caminho de literalmente a[b/c]d.
a{b,c}dé expansão de chaves , não está na especificação do POSIX. Aqui está a parte correspondente do manual do bash (ênfase minha):
A expansão de chaves é um mecanismo pelo qual strings arbitrárias podem ser geradas. Esse mecanismo é semelhante à expansão de nome de arquivo (consulte Expansão de nome de arquivo), mas os nomes de arquivo gerados não precisam existir . Os padrões a serem expandidos por chaves assumem a forma de um preâmbulo opcional,
seguido por uma série de strings separadas por vírgula ou uma expressão de sequência entre um par de chaves, seguida por um
postscript opcional. O preâmbulo é prefixado para cada string contida nas chaves, e o postscript é então anexado a cada string resultante, expandindo da esquerda para a direita.
De acordo com o comentário de @mosvy, isso apareceu pela primeira vez, cshmas o comportamento bashé diferente de cshoutros shells. Este tipo de expansão de chaves também está presente em glob(3).
Há outro tipo de expansão de chaves {a..z}que só apareceu após bash3.0, e há mais adicionados em bash4.0.
Em um shell onde o globbing está ativado, execute em uma pasta vazia, o seguinte resultado é retornado
$ echo a[bc]d
a[bc]d
$ echo a{b,c}d
abd acd
Em resposta ao comentário de @Jesse_b, se você estiver em um shell interativo e os dois se aplicarem, haverá a[bc]dmenos problemas para digitar. Por exemplo grep pattern [ab][12].txt.
Os dois são bem diferentes.
a[bc]d
é um padrão de nome de arquivo (em shells diferentes defish
). Ele se expandirá para os dois nomes de arquivoabd
eacd
se esses forem nomes de arquivos existentes no diretório atual.A
[...]
parte é uma expressão entre colchetes que corresponde a um único caractere dentre os listados (ou elementos de agrupamento quando os intervalos são incluídos). Para corresponder ao padrãoa[bc]d
, o caractere entre as stringsa
ed
em um nome de arquivo deve ser ab
ou ac
.Se
abd
existir, masacd
não existir, então só se expandirá paraabd
, e vice-versa.Se nem
abd
, nemacd
existir, dependendo do shell e das opções, ele acionaria um erro (original Unixsh
,(t)csh
,zsh
,fish
,bash -O failglob
) e possivelmente sairia do shell, ou deixaria o padrão não expandido¹ (shells do tipo Bourne erc
-like) ou expandir para nada (bash/zsh/yash -o nullglob
, algumas versões mais antigas defish
, Unix originalsh
e(t)csh
se houver outros globs correspondentes no mesmo comando).a{b,c}d
é uma expansão de chaves (em shells que os suportam). Ele se expandirá para as duas stringsabd
eacd
.A
{...}
parte é um conjunto de strings delimitado por vírgulas (neste exemplo; em algum shell, também pode ser um intervalo comoa..k
ou20..25
ou mais avançados como00..20..2
ou0..20..2%02d
), e a expansão é calculada combinando cada uma dessas strings com o flanqueamento cordasa
ed
. Essas strings podem ser maiores que um único caractere e também podem ser expansões de chaves.A expansão acontece independentemente de essas strings corresponderem a nomes de arquivos existentes ou não.
Se você estiver construindo strings, use uma expansão de chaves. Se você estiver combinando nomes de arquivos, use um padrão de nome de arquivo.
¹ Neste caso em particular,
a[bc]d
poderia ser o nome de um arquivo existente e é por isso que é potencialmente perigoso usar coisas comorm -f ./*.[ch]
nesses shells erm -f ./*.{c,h}
é um problema menor.a[bc]d
é de correspondência de padrões e faz parte do padrão POSIX. No POSIX, isso é introduzido como a "expressão de colchetes de padrão". Está documentado na seção 2.13 do manualA seção 2.13.3 também menciona algo que se comporta de maneira diferente do que se esperaria para regexs usuais quando é usado para expansão de nome de arquivo (ênfase minha)
a{b,c}d
é expansão de chaves , não está na especificação do POSIX. Aqui está a parte correspondente do manual do bash (ênfase minha):De acordo com o comentário de @mosvy, isso apareceu pela primeira vez,
csh
mas o comportamentobash
é diferente decsh
outros shells. Este tipo de expansão de chaves também está presente emglob(3)
.Há outro tipo de expansão de chaves
{a..z}
que só apareceu apósbash
3.0, e há mais adicionados embash
4.0.Em um shell onde o globbing está ativado, execute em uma pasta vazia, o seguinte resultado é retornado
Em resposta ao comentário de @Jesse_b, se você estiver em um shell interativo e os dois se aplicarem, haverá
a[bc]d
menos problemas para digitar. Por exemplogrep pattern [ab][12].txt
.