Controlla se una stringa corrisponde a un’espressione regolare nello script di Bash

Uno degli argomenti che il mio script riceve è una data nel seguente formato: yyyymmdd .

Voglio verificare se ottengo una data valida come input.

Come posso fare questo? Sto cercando di usare un’espressione regolare come: [0-9]\{\8}

Si può dire:

 [[ $date =~ ^[0-9]{8}$ ]] && echo "yes" 

O più preciso:

 [[ $date =~ ^[0-9]{4}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])$ ]] && echo "yes" # |^^^^^^^^ ^^^^^^ ^^^^^^ ^^^^^^ ^^^^^^^^^^ ^^^^^^ | # | | ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ | # | | | | | # | | \ | | # | --year-- --month-- --day-- | # | either 01...09 either 01..09 end of line # start of line or 10,11,12 or 10..29 # or 30, 31 

Cioè, puoi definire una regex in bash che corrisponde al formato che desideri. In questo modo puoi fare:

 [[ $date =~ ^regex$ ]] && echo "matched" || echo "did not match" 

Si noti che questo si basa sulla soluzione di Aleks-Daniel Jakimenko nella verifica del formato della data di input dell’utente in bash .


In shell come sh o fish – meno equipaggiato poi bash – puoi usare grep :

 (echo "$date" | grep -Eq ^regex$) && echo "matched" || echo "did not match" 

Nella versione 3 di bash puoi usare l’operatore ‘= ~’:

 if [[ "$date" =~ "[0-9]\{8\}" ]]; then echo "Valid date" else echo "Invalid date" fi 

Riferimento: http://tldp.org/LDP/abs/html/bashver3.html#REGEXMATCHREF

NOTA: la citazione dell’operatore corrispondente tra parentesi doppie, [[]], non è più necessaria a partire dalla versione 3.2 di Bash

Un buon modo per verificare se una stringa è una data corretta è usare la data del comando:

 if date -d "${DATE}" >/dev/null 2>&1 then # do what you need to do with your date else echo "${DATE} incorrect date" >&2 exit 1 fi 

expr match invece di =~ :

 expr match "$date" "^[0-9]\{8\}" >/dev/null && echo yes 

Questo è migliore della risposta attualmente accettata dell’uso =~ perché =~ corrisponderà anche alle stringhe vuote, che IMHO non dovrebbe. Supponiamo che badvar non sia definito, quindi [[ "1234" =~ "$badvar" ]]; echo $? [[ "1234" =~ "$badvar" ]]; echo $? fornisce (erroneamente) 0 , mentre expr match "1234" "$badvar" >/dev/null ; echo $? expr match "1234" "$badvar" >/dev/null ; echo $? dà il risultato corretto 1 .

Dobbiamo usare >/dev/null per hide il valore di output di expr match , che corrisponde al numero di caratteri abbinati o 0 se non viene trovata alcuna corrispondenza. Nota che il suo valore di uscita è diverso dal suo stato di uscita . Lo stato di uscita è 0 se c’è una corrispondenza trovata o 1 altrimenti.

In generale, la syntax per expr è:

 expr match "$string" '$substring' 

O:

 expr "$string" : '$substring' 

dove $substring è un’espressione regolare.