Qual é a diferença entre a[bc]d
e a{b,c}d
? Por que as pessoas usam a{b,c}d
quando já existem a[bc]d
?
brace-expansion
pattern-matching
Weijun Zhou
fonte
fonte
command a[bc]d
?ls
e tentar apenas caracteres únicos, eles parecerão funcionar da mesma maneira.Respostas:
Os dois são bem diferentes.
a[bc]d
é um padrão de nome de arquivo (em shells diferentes defish
). Ele será expandido para os dois nomes de arquivosabd
eacd
se esses são nomes de arquivos existentes no diretório atual.A
[...]
peça é uma expressão entre colchetes que corresponde a um único caractere dentre os listados (ou agrupa elementos quando os intervalos são incluídos). Para corresponder ao padrãoa[bc]d
, o caractere entre as seqüências de caracteresa
ed
em um nome de arquivo deve ser ab
ou ac
.Se
abd
existir, masacd
não existir, apenas expandiria paraabd
e vice-versa.Se nenhuma
abd
, nemacd
existir, dependendo do shell e as opções, isso provocaria um erro (original Unixsh
,(t)csh
,zsh
,fish
,bash -O failglob
) e, possivelmente, sair do shell, ou deixar o unexpanded¹ padrão (Bourne-like erc
-como conchas) ou expandir a nada (bash/zsh/yash -o nullglob
algumas versões mais antigas dofish
Unix originalsh
e(t)csh
se houver outros globs correspondentes no mesmo comando).a{b,c}d
é uma expansão de chave (em conchas que as suportam). Ele será expandido para as duas stringsabd
eacd
.A
{...}
parte é um conjunto delimitado por vírgulas de cordas (neste exemplo, em alguns concha, que também pode ser um intervalo, tais comoa..k
ou20..25
ou mais avançados aqueles como00..20..2
ou0..20..2%02d
), e a expansão é calculado através da combinação de cada uma destas cordas com o flanqueamento cordasa
ed
. Essas seqüências podem ter mais de um caractere e também podem ser expansões de chaves.A expansão ocorre independentemente de essas sequências corresponderem aos nomes de arquivos existentes ou não.
Se você estiver construindo cadeias, use uma expansão de chave. Se você estiver combinando nomes de arquivos, use um padrão de nome de arquivo.
¹ Nesse caso em particular,
a[bc]d
pode ser o nome de um arquivo existente, e é por isso que é potencialmente perigoso usar coisas comorm -f ./*.[ch]
essas conchas erm -f ./*.{c,h}
é menos problemático.fonte
a{b,c}d
, em , as partesb
ec
não precisam ser letras únicas; por exemploex{ten,ci}sion
. Enquantoex[tenci]sion
ou o que for, apenas corresponderá a uma dessas letras.a[bc]d
é a correspondência de padrões e faz parte do padrão POSIX. No POSIX, isso é introduzido como a "expressão de colchete 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 seria de se esperar para regexs comuns 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
e de outras conchas. Este tipo de expansão de chaves também está presente noglob(3)
.Há outro tipo de expansão de chaves
{a..z}
que apareceu apenas após obash
3.0 e há mais adicionados nobash
4.0.Em um shell em que 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 ao digitar. Por exemplogrep pattern [ab][12].txt
.fonte
csh
, muito antesbash
. Também está presente na função da biblioteca glob (3). A diferença é quebash
ele é executado antes de outras expansões:a=A; ab=A/B; ac=A/C; echo $a{b,c}
funcionará no bash de maneira diferente de qualquer outro shell.