Prueba de Bash: ¿qué hace "= ~"?


41
#!/bin/bash
INT=-5

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then

echo "INT is an integer."

else

echo "INT is not an integer." >&2

exit 1

fi

¿Qué hace la guía ~en la expresión regular inicial?



55
¿Has leído el manual de bash? ¿Qué encuentras poco claro?
icarus

3
Busque en la página del manual de bash = ~
Jeff Schaller

Respuestas:


46

En ~realidad, es parte del operador =~que realiza una coincidencia de expresión regular de la cadena a su izquierda con la expresión regular extendida a su derecha.

[[ "string" =~ pattern ]]

Tenga en cuenta que la cadena se debe citar y que la expresión regular no se debe citar.

Se utiliza un operador similar en el lenguaje de programación Perl.

Las expresiones regulares entendidas por bashson las mismas que GNU grepentiende con la -Ebandera, es decir, el conjunto extendido de expresiones regulares.


Algo fuera de tema, pero es bueno saberlo:

Cuando se compara con una expresión regular que contiene grupos de captura, la parte de la cadena capturada por cada grupo está disponible en la BASH_REMATCHmatriz. El cero / primera entrada en esta matriz corresponde a &en el patrón de sustitución de sed's comando de sustitución (o $&en Perl), que es el bit de la cadena que coincide con el patrón, mientras que las entradas en el índice 1 y en adelante corresponde a \1, \2, etc . en un sedpatrón de reemplazo (o $1, $2etc. , en Perl), es decir, los bits coincidentes por cada paréntesis.

Ejemplo:

string=$( date +%T )

if [[ "$string" =~ ^([0-9][0-9]):([0-9][0-9]):([0-9][0-9])$ ]]; then
  printf 'Got %s, %s and %s\n' \
    "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}"
fi

Esto puede generar

Got 09, 19 and 14

si la hora actual es 09:19:14.

El REMATCHbit del BASH_REMATCHnombre de la matriz proviene de "Regular Expression Match", es decir, "RE-Match".


En bashshells que no son de Bourne, también se puede usar exprpara la coincidencia de expresiones regulares limitadas (usando solo expresiones regulares básicas).

Un pequeño ejemplo:

$ string="hello 123 world"
$ expr "$string" : ".*[^0-9]\([0-9][0-9]*\)"
123

2
Es lo mismo que se grep -Eentiende solo en sistemas GNU y solo cuando se utiliza una variable sin comillas como patrón [[ $var = $pattern ]](ver [[ 'a b' =~ a\sb ]]vs p='a\sb'; [[ 'a b' =~ $p ]]). También tenga en cuenta que las citas de shell afectan el significado de los operadores RE y que algunos caracteres deben ser citados para la tokenización de shell que puede afectar el procesamiento de RE. [[ '\' =~ [\/] ]]devuelve falso ksh93tiene problemas aún peores. Ver zsh(o bash 3.1) para un enfoque más sensato en el que las citas de shell y RE están claramente separadas. La [construcción de zshy yashtambién tiene un =~operador.
Stéphane Chazelas

2
muy guay off-topic! +1 (
JJoao

@ StéphaneChazelas ¿Cómo es "más seguro" que ambos coincidan en zsh ?: [[ "This is a fine mess." =~ T.........fin*es* ]]; [[ "This is a fine mess." =~ T.........fin\*es\* ]]. ¿O que un citado *también coincide? [[ "This is a fine mess." =~ "T.........fin*es*" ]].
sorontar

Es más sensato (IMO) en que son reglas mucho más simples. Las citas de Shell y el escape de RE están claramente separadas. En [[ a =~ .* ]]o [[ a =~ '.*' ]]o [[ a =~ \.\* ]], el mismo .*RE se pasa al =~operador. OTH, en bash, [[ '\' =~ [)] ]]devuelve un error, ¿sabrías sin probar si [[ '\' =~ [\)] ]]coincide? ¿Qué tal [[ '\' =~ [\/] ]](lo hace en ksh93). ¿Qué tal c='a-z'; [[ a =~ ["$c"] ]](comparar con el =operador)? Ver también: [[ '\' =~ [^]"."] ]]el que devuelve falso ... Tenga en cuenta que se puede hacer shopt -s compat31en bashconseguir el zshcomportamiento.
Stéphane Chazelas

zsh/ bash -o compat31Comportamiento 's para [[ a =~ '.*' ]]también es consistente con [ a '=~' '.*' ](para [implementaciones que de apoyo =~) o expr a : '.*'. OTOH, no es consistente con [[ a = '*' ]]vs [[ a = * ]](pero luego, los globos son parte del lenguaje shell, mientras que los RE no lo son).
Stéphane Chazelas

4

Debería leer las páginas de manual de bash, debajo de la [[ expression ]]sección.

An additional binary operator, =~, is available, with the same precedence as == and !=. When it is used, the string to the right of the operator is considered an extended regular expression and matched accordingly (as in regex(3)).

Larga historia corta, =~es un operador, al igual que ==y !=. No tiene nada que ver con la expresión regular real en la cadena a su derecha.


¿Puedes encontrar algunos ejemplos que demuestren el uso de =~en la vida real ...?
George Vasiliou

1
@GeorgeVasiliou Lo uso con bastante frecuencia en scripts que colocan la salida de un comando en una variable. Luego se verifica la variable para ver si coincide con algún patrón de cadena. Esto es útil, por ejemplo, si desea realizar alguna acción basada en algún resultado de error de ese comando.
Michael Martinez

@Sokel Para algunos, "RTFM" es más fácil decirlo que hacerlo. ⋯ man [[ expresssion ]]y man [[no devuelven nada. help [[devuelve información útil, ya que es [[un comando bash interno, pero no dice si =~usa sintaxis de expresiones regulares básicas o extendidas. ⋯ El texto que citó es de la página de manual de bash . Me doy cuenta de que dijiste "lee las páginas de manual de bash" pero al principio, pensé que querías decir leer las páginas de manual de bash. En cualquier caso, man bashdevuelve un archivo enorme, que tiene 4139 líneas (72 páginas) de largo. Se puede buscar presionando /▒▒▒, que toma una expresión regular, cuyo sabor, como, =~no se especifica.
Alex Quinn
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.