bash
foi inicialmente projetado no final dos anos 80 como um clone parcial de ksh
alguns recursos interativos do csh / tcsh.
As origens do globbing devem ser encontradas nas conchas anteriores nas quais se baseia.
ksh
em si é uma extensão do shell Bourne. O próprio shell Bourne (lançado pela primeira vez em 1979 no Unix V7) foi uma implementação limpa do zero, mas não se afastou completamente do shell Thompson (o shell V1 -> V6) e incorporou recursos do shell Mashey.
Em particular, os argumentos de comando ainda estavam separados por espaços em branco, |
agora era o novo operador de canal, mas ^
ainda era suportado como uma alternativa (e também explica por que você faz [!a-z]
e não [^a-z]
), $1
ainda era o primeiro argumento para um script e a barra invertida ainda era o caractere de escape . Muitos operadores regexp ( ^\|$
) têm um significado especial no shell.
O shell Thompson contava com um utilitário externo para globbing. Quando sh
encontrado sem aspas *
, [
ou ?
s no comando, ele executaria o comando glob
.
rm *.txt
acabaria rodando glob como:
["glob", "rm", "*.txt"]
e glob acabaria executando rm
com a lista de arquivos que correspondem a esse padrão.
grep a.\*b *.txt
funcionaria glob
como:
["glob", "grep", "a.\252b", "*.txt"]
O *
acima foi citado definindo o 8º bit nesse caractere, impedindo glob
de tratá-lo como um curinga. glob
removeria esse bit antes de ligar grep
.
Para fazer o equivalente a regexps, isso teria sido:
regexp rm '\.txt$'
Ou:
regexp rm '^[^.].*\.txt$'
excluir arquivos de ponto.
A necessidade de escapar dos operadores, pois eles dobram como caracteres especiais do shell, o fato de que .
, comum nos nomes de arquivos, é um operador regexp, não é muito apropriado combinar nomes de arquivos e complicado para um iniciante. Na maioria dos casos, tudo o que você precisa são curingas que possam substituir um ( ?
) ou qualquer número ( *
) de caracteres.
Agora, diferentes invólucros adicionaram diferentes operadores de globbing. Atualmente, os globs ksh e zsh (e até certo ponto bash -O extglob
que implementam um subconjunto de globs ksh) são funcionalmente equivalentes aos regexps com uma sintaxe menos trabalhosa para usar com nomes de arquivos e a sintaxe atual do shell. Por exemplo, em zsh
(com extensão extendedglob), você pode:
echo a#.txt
se você deseja (improvável) corresponder a nomes de arquivos que consistem em sequências de a
seguidas por .txt
. Mais fácil do que echo (^a*\.txt$)
(aqui, usar chaves como uma maneira de isolar os operadores regex dos operadores de shell, que poderiam ter sido uma das maneiras pelas quais os shells poderiam lidar com isso).
echo (foo|bar|<1-20>).(#i)mpg
Para arquivos mpg (sem distinção entre maiúsculas e minúsculas) cujo nome base é foo, bar ou um número decimal de 1 a 20 ...
ksh93
agora também pode incorporar regexps (básico, estendido, parecido com perl ou "aumentado") em seus globos (embora seja bastante complicado) e até fornece uma ferramenta para converter entre glob e regexp ( printf %R
, printf %P
):
echo ~(Ei:.*\.txt)
de jogo (não oculto) txt arquivos com E Xtended expressões regulares, distinção entre maiúsculas i nsensitively.
rm -- ^[^.].*\.txt$
vez derm -- *.txt
?