Não em geral, mas facilmente neste caso:
shopt -s extglob
echo ${version/%+([0-9])/}
1.2.3.
É um exemplo inventado, mas aqui vai:
Digamos que eu tenha uma variável 1.2.3.4
contendo informações de versão e precise substituir o .4
no final por .5
version=1.2.3.4
echo ${version%.*}.5
1.2.3.5 #no problem
Mas quando eu tento "in-line" a substituição com /
e %
anchor
echo ${version/%.*/.5}
1.5
Bash faz uma substituição gananciosa. Existe uma maneira de fazer o bash elevar a substituição "não-avidamente" para que eu possa usar a substituição como um substituto para a abordagem anterior delete + append?
Eu acho que você não pode non-greedy
em search and replace
, você só pode fazê-lo com a remoção de substring. Das referências bash:
${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 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.
Para resolver isso, você deve definir extglob
:
shopt -s extglob
printf '%s\n' "${version/%.+([0-9])/.5}"
1.2.3.5
ou use algumas ferramentas como sed
ou perl
:
printf '%s\n' "$version" | perl -pe 's/\.\d+$/\.5/'
1.2.3.5