Pregunta
El siguiente código
number=1
if [[ $number =~ [0-9] ]]
then
echo matched
fi
obras.Sin embargo, si intento usar comillas en la expresión regular, se detiene:
number=1
if [[ $number =~ "[0-9]" ]]
then
echo matched
fi
Lo intenté "\[0-9\]"
, también.¿Qué me estoy perdiendo?
Curiosamente, guía de scripting avanzado de bash sugiere que esto debería funcionar.
Versión de bash 3.2.39.
Solución
Fue cambiado entre 3,1 y 3,2.Supongo que la guía avanzada necesita una actualización.
Esta es una descripción breve de las nuevas características agregadas a Bash-3.2 desde el lanzamiento de Bash-3.1.Como siempre, la página manual (doc/bash.1) es el lugar para buscar descripciones completas.
- Nuevas funciones en Bash
recorte
F.Citando el argumento de cadena en el operador [[comandante = ~ ahora fuerza la coincidencia de cadenas, como con los otros operadores de coincidencia de patrones.
Lamentablemente, esto romperá las cotizaciones existentes mediante scripts a menos que tenga la idea de almacenar patrones en variables y usarlos en lugar de las expresiones regulares directamente.Ejemplo a continuación.
$ bash --version
GNU bash, version 3.2.39(1)-release (i486-pc-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.
$ number=2
$ if [[ $number =~ "[0-9]" ]]; then echo match; fi
$ if [[ $number =~ [0-9] ]]; then echo match; fi
match
$ re="[0-9]"
$ if [[ $number =~ $re ]]; then echo MATCH; fi
MATCH
$ bash --version
GNU bash, version 3.00.0(1)-release (i586-suse-linux)
Copyright (C) 2004 Free Software Foundation, Inc.
$ number=2
$ if [[ $number =~ "[0-9]" ]]; then echo match; fi
match
$ if [[ "$number" =~ [0-9] ]]; then echo match; fi
match
Otros consejos
Bash 3.2 introdujo una opción de compatibilidad compat31 que revierte el comportamiento de citación de expresiones regulares de bash a 3.1
Sin compat31:
$ shopt -u compat31
$ shopt compat31
compat31 off
$ set -x
$ if [[ "9" =~ "[0-9]" ]]; then echo match; else echo no match; fi
+ [[ 9 =~ \[0-9] ]]
+ echo no match
no match
Con compat31:
$ shopt -s compat31
+ shopt -s compat31
$ if [[ "9" =~ "[0-9]" ]]; then echo match; else echo no match; fi
+ [[ 9 =~ [0-9] ]]
+ echo match
match
Enlace al parche:http://ftp.gnu.org/gnu/bash/bash-3.2-patches/bash32-039
GNU bash, versión 4.2.25(1) (x86_64-pc-linux-gnu)
Algunos ejemplos de coincidencia de cadenas y de expresiones regulares
$ if [[ 234 =~ "[0-9]" ]]; then echo matches; fi # string match
$
$ if [[ 234 =~ [0-9] ]]; then echo matches; fi # regex natch
matches
$ var="[0-9]"
$ if [[ 234 =~ $var ]]; then echo matches; fi # regex match
matches
$ if [[ 234 =~ "$var" ]]; then echo matches; fi # string match after substituting $var as [0-9]
$ if [[ 'rss$var919' =~ "$var" ]]; then echo matches; fi # string match after substituting $var as [0-9]
$ if [[ 'rss$var919' =~ $var ]]; then echo matches; fi # regex match after substituting $var as [0-9]
matches
$ if [[ "rss\$var919" =~ "$var" ]]; then echo matches; fi # string match won't work
$ if [[ "rss\\$var919" =~ "$var" ]]; then echo matches; fi # string match won't work
$ if [[ "rss'$var'""919" =~ "$var" ]]; then echo matches; fi # $var is substituted on LHS & RHS and then string match happens
matches
$ if [[ 'rss$var919' =~ "\$var" ]]; then echo matches; fi # string match !
matches
$ if [[ 'rss$var919' =~ "$var" ]]; then echo matches; fi # string match failed
$
$ if [[ 'rss$var919' =~ '$var' ]]; then echo matches; fi # string match
matches
$ echo $var
[0-9]
$
$ if [[ abc123def =~ "[0-9]" ]]; then echo matches; fi
$ if [[ abc123def =~ [0-9] ]]; then echo matches; fi
matches
$ if [[ 'rss$var919' =~ '$var' ]]; then echo matches; fi # string match due to single quotes on RHS $var matches $var
matches
$ if [[ 'rss$var919' =~ $var ]]; then echo matches; fi # Regex match
matches
$ if [[ 'rss$var' =~ $var ]]; then echo matches; fi # Above e.g. really is regex match and not string match
$
$ if [[ 'rss$var919[0-9]' =~ "$var" ]]; then echo matches; fi # string match RHS substituted and then matched
matches
$ if [[ 'rss$var919' =~ "'$var'" ]]; then echo matches; fi # trying to string match '$var' fails
$ if [[ '$var' =~ "'$var'" ]]; then echo matches; fi # string match still fails as single quotes are omitted on RHS
$ if [[ \'$var\' =~ "'$var'" ]]; then echo matches; fi # this string match works as single quotes are included now on RHS
matches
Como se mencionó en otras respuestas, poner la expresión regular en una variable es una forma general de lograr compatibilidad entre diferentes intento versiones.También puede utilizar esta solución alternativa para lograr lo mismo, manteniendo su expresión regular dentro de la expresión condicional:
$ number=1
$ if [[ $number =~ $(echo "[0-9]") ]]; then echo matched; fi
matched
$