Compruebe si una cadena coincide con una expresión regular en el guión Bash

Uno de los argumentos que recibe mi script es una fecha en el siguiente formato: yyyymmdd .

Quiero verificar si obtengo una fecha válida como entrada.

¿Cómo puedo hacer esto? Estoy tratando de usar una expresión regular como: [0-9]\{\8}

Puedes decir:

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

O más 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 

Es decir, puede definir una expresión regular en bash que coincida con el formato que desea. De esta manera puedes hacer:

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

Tenga en cuenta que esto se basa en la solución de Aleks-Daniel Jakimenko en la verificación del formato de fecha de entrada del usuario en bash .


En conchas como sh o fish – less equipped then bash – puedes usar grep :

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

En la versión 3 de bash, puede usar el operador ‘= ~’:

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

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

NOTA: La cita en el operador correspondiente dentro de los corchetes dobles, [[]] ya no es necesaria a partir de la versión 3.2 de Bash.

Una buena forma de probar si una cadena es una fecha correcta es usar la fecha 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 

Yo usaría expr match lugar de =~ :

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

Esto es mejor que la respuesta actualmente aceptada de usar =~ porque =~ también coincidirá con cadenas vacías, que en mi humilde opinión no debería. Supongamos que badvar no está definido, entonces [[ "1234" =~ "$badvar" ]]; echo $? [[ "1234" =~ "$badvar" ]]; echo $? da (incorrectamente) 0 , mientras que expr match "1234" "$badvar" >/dev/null ; echo $? expr match "1234" "$badvar" >/dev/null ; echo $? da el resultado correcto 1 .

Tenemos que usar >/dev/null para ocultar el valor de salida del expr match , que es el número de caracteres coincidentes o 0 si no se encuentra ninguna coincidencia. Tenga en cuenta que su valor de salida es diferente de su estado de salida . El estado de salida es 0 si se encuentra una coincidencia, o 1 de lo contrario.

Generalmente, la syntax para expr es:

 expr match "$string" '$substring' 

O:

 expr "$string" : '$substring' 

donde $substring es una expresión regular.