Esta questão é sobre a maneira correta de escrever literais de expressão regular em uma expressão de correspondência no bash.
Em zsh, a correspondência abaixo é bem-sucedida, como eu esperava:
% [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
0
Não é assim no bash:
$ [[ ' 123 ' =~ '^ [0-9]+ $' ]]; echo $?
1
Eu sei que este jogo tem sucesso no bash
$ ( regexp='^ [0-9]+ $'; [[ ' 123 ' =~ $regexp ]]; echo $? )
0
...mas requer atribuir a expressão regular a uma variável intermediária.
Minha pergunta é: Como se escreve um literal de expressão regular arbitrária em uma expressão de correspondência no bash?
É melhor colocá-lo em uma variável, conforme recomendado pelo manual de referência do Bash 3.2.4.2 Construções condicionais :
No entanto, para escrevê-lo diretamente dentro do teste estendido do bash, você precisa remover as aspas e escapar dos espaços:
No bash, a resposta canônica é: use um var
Isso funciona para espaços, barra invertida e muitas outras coisas:
Se você quiser escrevê-lo como um literal , você precisa jogar ( cuidadosamente ) com as citações.
Você precisa citar as partes que precisam ser literais e deixar as partes que devem ser interpretadas como regex sem aspas. O espaço precisa de cotação. Aqui usando backslah:
E aqui usando aspas duplas:
Mas essa "citação" fica muito confusa com coisas como uma barra invertida:
Mais simples, mais seguro:
E, não, você não precisa de um subshell para fazer isso (o parêntese em sua pergunta).
Sim, isso pode parecer irritante. E, sim, o comando que você apresentou funciona no zsh:
Mas citar é sempre um problema (em qualquer shell), o que deve acontecer com a barra invertida?:
Dobre!. Não é exatamente: literal .