L’altro giorno, da totale incompetente, stavo scrivendo uno script in bash per processare una pagina HTML, cercare un URL al suo interno, e scaricare il contenuto di quell’URL, in maniera ricorsiva per una serie di pagine; l’avevo già compilato in linguaggio AutoHotKey, tuttavia il mio PC con Windows non è sempre acceso, mentre il mio server domestico linux sì, quindi ho deciso che sarebbe stato opportuno imparare un po’ di linguaggio bash per rendere la procedura più efficiente.
In questo script devo estrarre un segmento di stringa contenuto tra due parole chiavi note, o “token” in inglese, per ottenere l’URL di cui ho bisogno; in AutoHotKey salvavo la posizione di entrambe le parole chiavi, quindi operavo una istruzione di substring tra questi due offset, e stavo cercando di far lo stesso in bash, siccome stavo pedissequamente traducendo lo script, piuttosto semplice, da un linguaggio all’altro.
Con mia sorpresa, questa non è una cosa che si può fare in bash, siccome l’unica operazione di ricerca di una stringa all’interno di un’altra stringa in realtà cerca il primo carattere della parola chiave; quindi, per esempio, se si cerca “mio” all’interno di “La melliflua pelliccia del mio gatto è marrone”, si ottiene 3, e non 27 come ci si aspetterebbe, perché come dicevo expr index "$string" $substring
restituisce solo la posizione del primo carattere di substring, quindi la prima posizione di “m” nella stringa.
In realtà, a me non serviva conoscere la posizione delle parole chiavi, purché riuscissi ad estrarre la stringa tra loro due, quindi ogni operazione che servisse a questo scopo andava bene; purtroppo me ne sono reso conto solo dopo aver buttato un’ora di tempo a cercare la soluzione, quindi pubblico i miei risultati per far risparmiare tempo a chi dovesse finire su questa pagina.
Fondamentalmente consiste nel tagliare dalla stringa tutto quello che precede la prima parola chiave (inclusa la prima chiave), e quindi tagliare dalla stringa così ottenuta tutto quello che segue la seconda patola chiave (seconda chiave inclusa):
#dichiarazione delle variabili testo="lungotestodacontrollare" primachiave="qualcosa" secondachiave="qualcosaltro" #elaborazione vera e propria stringacentrale=${testo#*$primachiave} stringacentrale=${stringacentrale%%$secondachiave*}
Questo restituisce $stringacentrale come la stringa contenuta tra la prima occorrenza di $primachiave (simbolo # singolo), e la prima occorrenza di $secondachiave (doppio simbolo %, che indica l’occorrenza più distante dalla fine della stringa).