bash regex con comillas?

El siguiente código

number=1 if [[ $number =~ [0-9] ]] then echo matched fi 

trabajos. Si trato de usar comillas en la expresión regular, sin embargo, se detiene:

 number=1 if [[ $number =~ "[0-9]" ]] then echo matched fi 

Intenté "\[0-9\]" , también. ¿Qué me estoy perdiendo?

Curiosamente, la guía de scripts avanzada de bash sugiere que esto debería funcionar.

Bash versión 3.2.39.

Fue cambiado entre 3.1 y 3.2 . Supongo que la guía avanzada necesita una actualización.

Esta es una breve descripción de las nuevas características agregadas a bash-3.2 desde el lanzamiento de bash-3.1. Como siempre, la página del manual (doc / bash.1) es el lugar para buscar descripciones completas.

  1. Nuevas características en Bash

recorte

F. Citando el argumento de cadena para el operador [[command’s = ~ ahora fuerza la coincidencia de cadenas, como con los otros operadores de coincidencia de patrones.

Lamentablemente, esto romperá la cotización existente usando 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 

Bash 3.2 introdujo una opción de compatibilidad compatible31 que revierte el comportamiento de cita de expresión regular 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) – liberación (x86_64-pc-linux-gnu)

Algunos ejemplos de coincidencia de cadenas y 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 eg 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 menciona en otras respuestas, poner la expresión regular en una variable es una forma general de lograr compatibilidad con diferentes versiones de bash . También puede usar esta solución para lograr lo mismo, mientras mantiene su expresión regular dentro de la expresión condicional:

 $ number=1 $ if [[ $number =~ $(echo "[0-9]") ]]; then echo matched; fi matched $