bash: come utilizzare più manipolazioni di stringhe (espansione dei parametri) in un unico passaggio?
Ho string=substr1-substr2-substr3.substr4dove le sottostringhe sono di lunghezza variabile. Voglio estrarre substr3da stringe sto pensando di farlo utilizzando le ${string##pattern}e ${string%pattern}espansioni manipolazione delle stringhe. Utilizzando questo approccio, è chiaro che devo eseguire ${string##*-}ed eseguire ${string%.*}l'espansione risultante, o viceversa. Le mie domande sono:
- è questa la scelta migliore?
- Se sì, come posso eseguire entrambi in un unico passaggio? Quando provo a fare qualcosa di simile
${string##*-${string%.*}}o${string%.*${string##*-}}ricevo semplicemente l'intera stringa. Mi rendo conto che potrei sempre fare l'estrazione in due passaggi assegnando una variabile intermedia al risultato del primo passaggio e poi manipolandolo; ma voglio farlo in un solo passaggio. Come posso procedere?
TIA!
Risposte
Dato
string=substr1-substr2-substr3.substr4
${string%.*} è
substr1-substr2-substr3
così ${string##*-${string%.*}}è
${string##*-substr1-substr2-substr3}
che significa rimuovere dall'inizio di string, tutto fino ae incluso -substr1-substr2-substr3. Ma non esiste una sottostringa di questo tipo string, poiché non c'è un trattino davanti substr1, quindi ottieni la stringa originale.
Quello che probabilmente vuoi è
string=substr1-substr2-substr3.substr4
result="${string%.*}" result="${result##*-}"
che porta al resultcontenimento substr3.
In Zsh, potresti farlo in un unico passaggio:, ma non funziona in Bash.result=${${string%.*}##*-}
In Bash, sei limitato all'uso di espansioni sul lato destro di #o %, e questo non ti aiuta qui poiché devi rimuovere parti sia dall'inizio che dalla fine della stringa.
In alternativa, se $stringnon contiene caratteri di nuova riga, puoi usare
IFS=.- read -r a b c d <<< "$string"
e leggere substr3da c.
In tal caso, a seconda della shell e della dimensione della stringa, il contenuto di $stringverrà memorizzato in un file temporaneo o alimentato attraverso una pipe che readleggerà la prima riga e la dividerà in base a $IFS.