Há algumas coisas importantes que você deve saber sobre a [[ ]]construção do bash . O primeiro:
A divisão de palavras e a expansão do nome do caminho não são executadas nas palavras entre [[e ]]; Expansão til, expansão de parâmetro e variável, expansão aritmética, substituição de comando, substituição de processo e remoção de cotação são executadas.
A segunda coisa:
Um operador binário adicional, '= ~', está disponível, ... a string à direita do operador é considerada uma expressão regular estendida e correspondida de acordo ... Qualquer parte do padrão pode ser citada para forçar a correspondência como uma string .
Conseqüentemente, $vem qualquer lado do =~será expandido para o valor daquela variável, mas o resultado não será dividido por palavras ou expandido pelo nome do caminho. Em outras palavras, é perfeitamente seguro deixar as expansões variáveis sem aspas no lado esquerdo, mas você precisa saber que as expansões variáveis acontecerão no lado direito.
Então, se você escrever: [[ $x =~ [$0-9a-zA-Z] ]]o $0interior do regex à direita será expandido antes do regex é interpretado, o que provavelmente fará com que o regex para não compilar (a menos que a expansão das $0extremidades com um símbolo de dígitos ou pontuação cujo valor ASCII é menor do que um dígito). Se você citar o lado direito da mesma maneira [[ $x =~ "[$0-9a-zA-Z]" ]], o lado direito será tratado como uma string comum, não uma regex (e $0ainda será expandido). O que você realmente quer neste caso é[[ $x =~ [\$0-9a-zA-Z] ]]
Da mesma forma, a expressão entre [[e ]]é dividida em palavras antes que a regex seja interpretada. Portanto, os espaços no regex precisam ter escape ou entre aspas. Se você queria para combinar letras, números ou espaços que você poderia usar: [[ $x =~ [0-9a-zA-Z\ ] ]]. Outros caracteres também precisam de escape, como #, o que iniciaria um comentário se não fosse citada. Claro, você pode colocar o padrão em uma variável:
pat="[0-9a-zA-Z ]"
if [[ $x =~ $pat ]]; then ...
Para regexes que contêm muitos caracteres que precisariam ser escapados ou citados para passar pelo lexer do bash, muitas pessoas preferem esse estilo. Mas cuidado: neste caso, você não pode citar a expansão da variável:
if [[ $x =~ "$pat" ]]; then ...
Finalmente, acho que o que você está tentando fazer é verificar se a variável contém apenas caracteres válidos. A maneira mais fácil de fazer essa verificação é certificar-se de que não contém um caractere inválido. Em outras palavras, uma expressão como esta:
valid='0-9a-zA-Z $%&#'
if [[ ! $x =~ [^$valid] ]]; then ...
!nega o teste, transformando-o em um operador "não corresponde", e uma [^...]classe de caractere regex significa "qualquer caractere diferente de ...".
A combinação de expansão de parâmetro e operadores regex pode tornar a sintaxe da expressão regular do bash "quase legível", mas ainda existem algumas pegadinhas. (Não há sempre?) Uma é que você não poderia colocar] em $valid, mesmo que $validforam citados, exceto no início. (Essa é uma regra Posix regex: se você quiser incluir ]em uma classe de caractere, ela precisa ir no início. -Pode ir no início ou no final, então se você precisa de ambos ]e -, você precisa começar ]e terminar com -, levando à regex "Eu sei o que estou fazendo" emoticon: [][-])