Interruptor de função de caracteres especiais no bash

2

Em que base o papel do asterisco continua mudando?

CASE 1: 
var1=abcd-1234-defg 
echo ${var1#*-*}        # RESULT: 1234-defg

CASE 2: 
stringZ=abcABC123ABCabc 
echo 'expr match "$stringZ" '\(abc[A-Z]*.2\)''  # RESULT: abcABC12

Quando e como o papel do asterisco é decidido?

CASE 3:
path_name="/home/bozo/ideas/thoughts.for.today"
echo ${path_name##/*/}  # RESULT : thoughts.for.today

Neste caso, confrontei / com o papel de caractere de escape aqui, ou seja, tentando escapar da característica básica de * . Bem, eu estava errado. Então, como os papéis desses personagens especiais são decididos e por quem?

CASE 4: 
var1=abcd--1234-defg 
echo ${var1#*-*}        # RESULT: -1234-defg  & i was expecting 1234-defg

O CASO 4 é semelhante ao CASO 1, mas com uma diferença como pode ser visto em abcd-- , e eu estava esperando 1234-defg , mas o resultado acabou sendo o mesmo que no caso 1.

Foi assim que interpretei *-* no CASO 4:

The shell would look for everything from the start of the var1 till it finds - OR -- OR ---

Por que minha interpretação no contexto do CASO 4 está incorreta?

    
por Sudhish Vln 04.12.2015 / 07:03

2 respostas

3

Isso porque * teve um significado diferente em seus testes.

Em caso 1 , caso 3 e caso 4 , ele é usado como um correspondência de padrões . Em caso 2 , é um metacaractere expressão regular ( ou quantificador ou estrela de Kleene ).

Na correspondência de padrão, o caractere * corresponderá a qualquer string, incluir string nula, a* corresponderá a qualquer string com a , exemplo a , aa , ab , mas não b

Na expressão regular, * quantifier corresponde a zero ou mais ocorrências do token precedente, a* corresponderá a zero ou mais a sequências, exemplo '' , a , aa , aaa , ab , b .

Com isso em mente, seu caso 4 será interpretado como corresponde a qualquer string contendo - , porque foi usado como correspondência de padrão, sua explicação em questão é usado como uma expressão regular.

Portanto, abcd--1234-defg , a menor correspondência da sub-string *-* é abcd- , e a correspondência mais longa é a string inteira. Desde quando você usa o formulário ${var1#*-*} , que é uma Expansão de Parâmetro para remover o O prefixo mais curto em $var1 match *-* , você obteve -1234-defg , porque o prefixo mais curto correspondido é abcd- .

    
por 04.12.2015 / 08:16
2

Há duas coisas para entender:

  1. Em uma glob, * corresponde a zero ou mais de qualquer caractere

  2. O formulário ${var1#*-*} remove a correspondência mais curta .

Assim, ${var1#*-*} só será removido até o primeiro traço, porque essa é a correspondência mais curta .

Para fins de conclusão, observe que ${var1##*-*} removeria a correspondência mais longa.

Exemplos

Em cada caso abaixo, o prefixo correspondente mais curto é removido:

$ var1=abcd-1234-defg 
$ echo ${var1#*}
abcd-1234-defg
$ echo ${var1#*-}
1234-defg
$ echo ${var1#*-*}
1234-defg
$ echo ${var1#*-*-}
defg
$ echo ${var1#*-*-*}
defg

Compare o texto acima com o caso ## , que remove o prefixo correspondente maior :

$ echo ${var1##*-}
defg
$ echo ${var1##*-*}

$ 

Documentação

De man bash :

${parameter#word}
${parameter##word}

Remove matching prefix pattern. The word is expanded to produce a pattern just as in pathname expansion. If the pattern matches the beginning of the value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pattern (the # case) or the longest matching pattern (the ## case) deleted. If parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with @ or *, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list. [Emphasis added.]

    
por 04.12.2015 / 07:51