Padrão correspondente [duplicado]

1

Estou tentando seguir o Bash Cookbook para aprender sobre o Bash Scripting. Eu estou no exemplo 6.8 Testando com expressão regular.

Eu tenho o seguinte script:

#!/usr/bin/env bash
# cookbook filename: trackmatch

for CDTRACK in *
do
     if [[ "$CDTRACK" =~ "([[:alpha:][:blank:]]*)- ([[:digit:]]*) - (.*)$" ]]
then
    echo ${BASH_REMATCH[2]}
else
    echo Error $CDTRACK
fi
done

Eu aplico isso a alguns arquivos no meu diretório:

Ludwig van Beethovern - 02 - Adagio un poco mosso.ogg

Ludwig van Beethovern - 01 - Allegro.ogg

Sempre recebo um erro. O problema parece estar na seção ([[:alpha:][:blank:]]*)- ([[:digit:]]*) - do código. Quando eu tenho a declaração if como: if [[ "$CDTRACK" =~ "(.*)$" ]] então não há erro.

Quaisquer pensamentos sobre o que estou fazendo errado?

Estou executando o código no AWS, Bash v 4.2

    
por JohnB 01.05.2016 / 16:34

1 resposta

6

ShellCheck é um bom começo para programação bash. Dá dicas bastante úteis:

Line 6:
if [[ "$CDTRACK" =~ "([[:alpha:][:blank:]]*)- ([[:digit:]]*) - (.*)$" ]]
                    ^-- SC2076: Don't quote rhs of =~, it'll match literally rather than as a regex.

O Regex não pode ser citado assim. Exemplo de trabalho com caracteres especiais com escape (basicamente espaços):

if [[ "$CDTRACK" =~ ([[:alpha:][:blank:]]*)-\ ([[:digit:]]*)\ -\ (.*)$ ]]

ou como glenn jackman proposto, citando apenas os outros personagens (o que parece estranho para pessoas que usam linguagens diferentes, mas também funciona):

if [[ "$CDTRACK" =~ ([[:alpha:][:blank:]]*)"- "([[:digit:]]*)" - "(.*)$ ]]

Oneliner para testar uma string existente:

if [[ "Ludwig van Beethovern - 02 - Adagio un poco mosso.ogg" =~ ([[:alpha:][:blank:]]*)-\ ([[:digit:]]*)\ -\ (.*)$ ]]; then echo "${BASH_REMATCH[2]}"; fi
    
por 01.05.2016 / 16:53