Existe uma maneira de substituir a última ocorrência de correspondência usando uma substituição de variável de shell?

2
% x=abracadabra
% echo ${x//a/o}
obrocodobro

Hmph ...

Existe uma maneira de substituir a última ocorrência de um padrão usando as subestações do shell (IOW, sem distribuir sed , awk , perl , etc.)?

    
por kjo 27.02.2018 / 03:39

2 respostas

3

Observação: isso substitui uma ocorrência final - não exatamente o mesmo que "a última ocorrência"

Do Manual de referência do bash Seção 3.5.3 Expansão do parâmetro shell :

${parameter/pattern/string} 

The pattern is expanded to produce a pattern just as in filename expansion. Parameter is expanded and the longest match of pattern against its value is replaced with string. If pattern begins with ‘/’, all matches of pattern are replaced with string. Normally only the first match is replaced. If pattern begins with ‘#’, it must match at the beginning of the expanded value of parameter. If pattern begins with ‘%’, it must match at the end of the expanded value of parameter. If string is null, matches of pattern are deleted and the / following pattern may be omitted. If the nocasematch shell option (see the description of shopt in The Shopt Builtin) is enabled, the match is performed without regard to the case of alphabetic characters. If parameter is ‘@’ or ‘’, the substitution 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 substitution operation is applied to each member of the array in turn, and the expansion is the resultant list.

Então

$ x=abracadabra
$ echo "${x/%a/o}"
abracadabro
    
por 27.02.2018 / 03:49
1

Você pode fazer isso com substituições de shell, o que é um pouco complicado. Você basicamente pega tudo antes do padrão inserir o seu substituto e depois pega tudo depois do padrão. Para o seu exemplo, ficaria assim:

    x=abracadabra
    echo "${x%a*}o${x##*a}"

EDIT: Ou apenas faça o que a chave de aço sugeriu nos comentários.

    
por 27.02.2018 / 03:46