Ci sono un paio di cose importanti da sapere sulla [[ ]]costruzione di bash . Il primo:
La suddivisione delle parole e l'espansione del nome del percorso non vengono eseguite sulle parole comprese tra [[e ]]; Vengono eseguite l'espansione della tilde, l'espansione di parametri e variabili, l'espansione aritmetica, la sostituzione dei comandi, la sostituzione dei processi e la rimozione delle quote.
La seconda cosa:
È disponibile un operatore binario aggiuntivo, '= ~', ... la stringa a destra dell'operatore è considerata un'espressione regolare estesa e corrisponde di conseguenza ... Qualsiasi parte del modello può essere citata per forzarne la corrispondenza come una stringa .
Di conseguenza, $vsu entrambi i lati di =~verrà espanso al valore di quella variabile, ma il risultato non sarà suddiviso in parole o espanso nel nome del percorso. In altre parole, è perfettamente sicuro lasciare le espansioni variabili non quotate sul lato sinistro, ma è necessario sapere che le espansioni variabili avverranno sul lato destro.
Quindi se scrivi :, [[ $x =~ [$0-9a-zA-Z] ]]l' $0interno della regex a destra verrà espanso prima che la regex venga interpretata, il che probabilmente causerà la mancata compilazione dell'espressione regolare (a meno che l'espansione della regex non termini $0con una cifra o un simbolo di punteggiatura il cui valore ascii sia inferiore a una cifra). Se si cita il lato destro in questo modo [[ $x =~ "[$0-9a-zA-Z]" ]], il lato destro verrà trattato come una stringa normale, non come un'espressione$0 regolare (e sarà comunque espanso). Quello che vuoi veramente in questo caso è[[ $x =~ [\$0-9a-zA-Z] ]]
Allo stesso modo, l'espressione tra [[e ]]viene suddivisa in parole prima che la regex venga interpretata. Quindi gli spazi nella regex devono essere preceduti da caratteri di escape o citati. Se si voleva abbinare lettere, cifre o spazi si potrebbe usare: [[ $x =~ [0-9a-zA-Z\ ] ]]. Allo stesso modo è necessario eseguire l'escape di altri caratteri, come #, che inizierebbe un commento se non citato. Ovviamente puoi inserire il pattern in una variabile:
pat="[0-9a-zA-Z ]"
if [[ $x =~ $pat ]]; then ...
Per le regex che contengono molti caratteri che dovrebbero essere sottoposti a escape o citati per passare attraverso il lexer di bash, molte persone preferiscono questo stile. Ma attenzione: in questo caso, non puoi citare l'espansione della variabile:
if [[ $x =~ "$pat" ]]; then ...
Infine, penso che quello che stai cercando di fare sia verificare che la variabile contenga solo caratteri validi. Il modo più semplice per eseguire questo controllo è assicurarsi che non contenga un carattere non valido. In altre parole, un'espressione come questa:
valid='0-9a-zA-Z $%&#'
if [[ ! $x =~ [^$valid] ]]; then ...
!nega il test, trasformandolo in un operatore "non corrisponde" e una [^...]classe di caratteri regex significa "qualsiasi carattere diverso da ...".
La combinazione dell'espansione dei parametri e degli operatori regex può rendere la sintassi delle espressioni regolari bash "quasi leggibile", ma ci sono ancora alcuni trucchi. (Non Ci sono sempre?) La prima è che non si poteva mettere ]in $valid, anche se $validsono stati citati, ad eccezione proprio all'inizio. (Questa è una regola regex di Posix: se vuoi includere ]in una classe di caratteri, deve andare all'inizio. -Può andare all'inizio o alla fine, quindi se hai bisogno di entrambi ]e -, devi iniziare ]e finire con -, che porta alla espressione regolare "io so quello che sto facendo" emoticon: [][-])