bash: Como usar várias manipulações de string (expansão de parâmetro) em uma etapa?
Eu tenho string=substr1-substr2-substr3.substr4
onde as substrings são de comprimento variável. Eu quero extrair substr3
a partir string
e estou pensando em fazê-lo usando os ${string##pattern}
e ${string%pattern}
expansões de manipulação de string. Usando essa abordagem, fica claro que preciso executar ${string##*-}
e executar ${string%.*}
na expansão resultante ou vice-versa. Minhas perguntas são:
- esta é a melhor escolha?
- Se sim, como faço para executar ambos em uma única etapa? Quando eu tento fazer algo como
${string##*-${string%.*}}
ou${string%.*${string##*-}}
simplesmente recupero a string inteira. Percebo que sempre posso fazer a extração em duas etapas atribuindo uma variável intermediária ao resultado da primeira etapa e, em seguida, manipulando isso; mas quero fazer isso em uma etapa. Como proceder?
TIA!
Respostas
Dado
string=substr1-substr2-substr3.substr4
${string%.*}
é
substr1-substr2-substr3
então ${string##*-${string%.*}}
é
${string##*-substr1-substr2-substr3}
o que significa remover desde o início string
, tudo até e incluindo -substr1-substr2-substr3
. Mas não existe tal substring string
, pois não há travessão na frente de substr1
, então você obtém a string original.
O que você provavelmente quer é
string=substr1-substr2-substr3.substr4
result="${string%.*}" result="${result##*-}"
o que leva a result
containg substr3
.
No Zsh, você poderia fazer isso em uma etapa:, mas isso não funciona no Bash.result=${${string%.*}##*-}
No Bash, você está limitado a usar expansões no lado direito de #
ou %
, e isso não o ajuda aqui, pois você precisa remover partes do início e do final da corda.
Como alternativa, se $string
não contiver caracteres de nova linha, você pode usar
IFS=.- read -r a b c d <<< "$string"
e ler substr3
off partir c
.
Nesse caso, dependendo do shell e do tamanho da string, o conteúdo de $string
será armazenado em um arquivo temporário ou alimentado por um tubo que read
irá ler a primeira linha e dividi-la de acordo com $IFS
.