Estrarre una stringa, secondo uno schema, in uno script bash


17

In bash, supponiamo che io abbia una stringa strname:

strname="ph7go04325r"

Vorrei estrarre i caratteri tra il primo "3" e l' ultimo "r" carattere strname, salvando il risultato in una stringa strresult. Nell'esempio sopra, il risultato strresultsarebbe:

strresult="25"

Il primo "3"carattere non è necessariamente nella posizione di stringa 8 in strname; allo stesso modo, l'ultimo non"r" è necessariamente nella posizione di stringa 11. Pertanto, entrambe le seguenti stringhe dovrebbero produrre :strnamestrresult="25"

strname="ph11go04325raa"
strname="325r"
strname="rgo04325raa"

Inoltre, strname=ph12go04330raa"dovrebbe cedere strresult="30".

Sono nuovo allo scripting bash e non so da dove iniziare a fare corrispondenze di stringhe come questa. Hai qualche suggerimento?

Risposte:


28

È possibile utilizzare un regex in bash (3.0 o successivo) per ottenere questo risultato:

if [[ $strname =~ 3(.+)r ]]; then
    strresult=${BASH_REMATCH[1]}
else
    echo "unable to parse string $strname"
fi

In bash, i gruppi di acquisizione da un regex sono collocati nella matrice speciale BASH_REMATCH. L'elemento 0 contiene l'intera corrispondenza e 1 contiene la corrispondenza per il primo gruppo di acquisizione.


10

Nella shsintassi standard (quindi funzionerebbe con qualsiasi versione basho qualsiasi altra shell conforme a POSIX), faresti:

case $strname in
  (*3*r*) 
    strresult=${strname#*3}
    strresult=${strresult%r*};;
  (*)
    printf >&2 '%s\n' "Unable to parse string $strname"
esac

Vedi anche la vecchia exprsoluzione che funzionerà anche su Unices di 35 anni:

expr "x$strname" : 'x[^3]*3\(.*\)r'

La vecchia stranezza con exprè che se la corrispondenza fallisce si ottiene uno stato di uscita diverso da zero (bene), ma si ottiene anche uno stato di uscita diverso da zero se le stringhe restituite si risolvono in 0 (come con strname=zz300rzz).


Penso che il tuo fraseggio implichi erroneamente che ciò può essere fatto solo con versioni precedenti di bash. L'espansione dei parametri è, ovviamente, ancora un ottimo approccio nelle shell moderne.
Kojiro,

1
@kojiro, capisco cosa intendi. La formulazione iniziale era di dare seguito alla risposta della Giordania. Ho aggiornato la mia risposta.
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.