bash: Como usar várias manipulações de string (expansão de parâmetro) em uma etapa?
Eu tenho string=substr1-substr2-substr3.substr4onde as substrings são de comprimento variável. Eu quero extrair substr3a partir stringe 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 resultcontaing 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 $stringnão contiver caracteres de nova linha, você pode usar
IFS=.- read -r a b c d <<< "$string"
e ler substr3off partir c.
Nesse caso, dependendo do shell e do tamanho da string, o conteúdo de $stringserá armazenado em um arquivo temporário ou alimentado por um tubo que readirá ler a primeira linha e dividi-la de acordo com $IFS.