regex - test - Usando match para encontrar subcadenas en cadenas con solo bash
regular expression for a string (4)
Aunque estoy casi seguro de que esto ha sido cubierto, parece que no puedo encontrar nada específico para esto. A medida que continúo mi viaje aprendiendo bash, sigo encontrando partes en las que estoy desconcertado sobre por qué las cosas suceden de la manera en que lo hacen.
Es muy probable que buscar y reemplazar o simplemente hacer coincidir cadenas secundarias en cadenas sea una de las primeras cosas que haces cuando escribes scripts. Pero, tratar de apegarse a un solo idioma o conjunto de herramientas es difícil de hacer en bash, ya que puede resolver la mayoría del problema de múltiples maneras. Hago lo mejor que puedo para mantener el nivel más bajo posible con bash. Me he encontrado con un problema que necesito que alguien me explique.
Hacer subcadena una búsqueda en bash con coincidencia me da resultados diferentes dependiendo de la expresión regular que uso, y no estoy seguro de por qué.
#!/bin/bash
Stext="Hallo World"
echo `expr "$Stext" : ''^/(.[a-z]*/)''` # Hallo
echo `expr "$Stext" : ''.*World''` # 11
Aunque ambos buscan una palabra, creo que ambos no devuelven lo que encuentran. ¿Por qué?
Ambas expresiones son equivalentes, la diferencia es la expresión regular que usas:
$ echo `expr "$Stext" : ''^/(.[a-z]*/)''`
Hallo
$ echo `expr "$Stext" : ''^.[a-z]*''`
5
$ echo `expr "$Stext" : ''/(.*World/)''`
Hallo World
$ echo `expr "$Stext" : ''.*World''`
11
Como puede ver, paréntesis es lo que hace la diferencia para devolver la duración del partido o el partido en sí.
Puede encontrar más ejemplos en el Capítulo 10 de la Guía Avanzada de Bash-Scripting.
Hice esta simple función:
match() {
TRUE=1
FALSE=0
match_return=0
echo $1 | grep $2 >/dev/null
[ $? -eq 0 ] && match_return=$TRUE || match_return=$FALSE
}
Uso:
match Testing Test ; [ $match_return -eq 1 ] && echo "match!" || echo "nope"
Código completo: https://gist.github.com/TeeBSD/5121b3711fad40a09455
Para búsquedas rápidas de cadenas ... Una opción es grep.
Si no se encuentra, devuelve vacío, de lo contrario es una coincidencia:
found=`echo $big | grep -e $short`
if [ ! -z $found ]; then echo ''There is a match''; else echo ''No no''; fi
Puede usar la variable BASH_REMATCH
en bash
para obtener la cadena coincidente:
$ Stext="Hallo World"
$ [[ $Stext =~ ^.[a-z]* ]] && echo $BASH_REMATCH
Hallo
$ [[ $Stext =~ ^(.[a-z]*) ]] && echo ${BASH_REMATCH[1]}
Hallo
Las subcadenas emparejadas por subexpresiones entre paréntesis dentro de la expresión regular se guardan en la variable de matriz BASH_REMATCH . El elemento de BASH_REMATCH con índice 0 es la parte de la cadena que coincide con la expresión regular completa. El elemento de BASH_REMATCH con índice n es la parte de la cadena que coincide con la enésima subexpresión entre paréntesis.