Bash
Patrón de coincidencia y expresiones regulares
Buscar..
Sintaxis
- $ shopt -u opción # Desactivar la 'opción' incorporada de Bash
- Opción $ shopt -s # Activar la 'opción' incorporada de Bash
Observaciones
Clases de personajes
Las clases de caracteres válidos para []
glob están definidas por el estándar POSIX:
alnum alfa ascii en blanco cntrl dígito gráfico letra inferior espacio punteado palabra superior xdigit
Dentro de []
se puede usar más de una clase de caracteres o rango, por ejemplo,
$ echo a[a-z[:blank:]0-9]*
coincidirá con cualquier archivo que comience con una a
seguido de una letra minúscula o un espacio en blanco o un dígito.
Sin embargo, debe tenerse en cuenta que un globo []
solo puede ser completamente negado y no solo partes de él. El carácter de negación debe ser el primer carácter después de la apertura [
, por ejemplo, esta expresión coincide con todos los archivos que no comienzan con una a
$ echo [^a]*
Lo siguiente hace coincidir todos los archivos que comienzan con un dígito o un ^
$ echo [[:alpha:]^a]*
No coincide con cualquier archivo o carpeta que comienza con la letra a excepción de una a
porque el ^
se interpreta como un literal ^
.
Escapar de personajes glob
Es posible que un archivo o carpeta contenga un carácter global como parte de su nombre. En este caso, se puede escapar un globo con un \
precedente en orden para una coincidencia literal. Otro método consiste en utilizar el doble ""
o de un solo ''
cita para abordar el archivo. Bash no procesa globos que están encerrados dentro de ""
o ''
.
Diferencia a las expresiones regulares
La diferencia más significativa entre globs y expresiones regulares es que una expresión regular válida requiere un calificador y un cuantificador. Un calificador identifica con qué coincidir y un cuantificador indica con qué frecuencia debe coincidir con el calificador. El RegEx equivalente al *
glob es .*
Donde .
significa cualquier carácter y *
representa cero o más coincidencias del carácter anterior. El RegEx equivalente para el ?
glob es .{1}
. Como antes, el calificador .
coincide con cualquier carácter y el {1}
indica que coincide exactamente una vez con el calificador anterior. Esto no debe confundirse con el ?
cuantificador, que coincide con cero o una vez en un RegEx. El []
glob se puede usar de la misma manera en un RegEx, siempre que esté seguido de un cuantificador obligatorio.
Expresiones Regulares Equivalentes
Globo | RegEx |
---|---|
* | .* |
? | . |
[] | [] |
Compruebe si una cadena coincide con una expresión regular
Compruebe si una cadena consta de exactamente 8 dígitos:
$ date=20150624
$ [[ $date =~ ^[0-9]{8}$ ]] && echo "yes" || echo "no"
yes
$ date=hello
$ [[ $date =~ ^[0-9]{8}$ ]] && echo "yes" || echo "no"
no
El * glob
Preparación
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
El asterisco * es probablemente el globo más utilizado. Simplemente coincide con cualquier cadena
$ echo *acy
macy stacy tracy
Un solo * no coincidirá con los archivos y carpetas que residen en subcarpetas
$ echo *
emptyfolder folder macy stacy tracy
$ echo folder/*
folder/anotherfolder folder/subfolder
El ** glob
Preparación
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -s globstar
Bash es capaz de interpretar dos asteriscos adyacentes como un solo globo. Con la opción globstar
activada, se puede usar para hacer coincidir carpetas que residen más profundamente en la estructura del directorio.
echo **
emptyfolder folder folder/anotherfolder folder/anotherfolder/content folder/anotherfolder/content/deepfolder folder/anotherfolder/content/deepfolder/file folder/subfolder folder/subfolder/content folder/subfolder/content/deepfolder folder/subfolder/content/deepfolder/file macy stacy tracy
El **
se puede pensar en una expansión del camino, sin importar qué tan profundo sea el camino. Este ejemplo coincide con cualquier archivo o carpeta que comience con deep
, sin importar qué tan profundo esté anidado:
$ echo **/deep*
folder/anotherfolder/content/deepfolder folder/subfolder/content/deepfolder
Los ? glob
Preparación
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
El ?
simplemente coincide exactamente con un personaje
$ echo ?acy
macy
$ echo ??acy
stacy tracy
El [] glob
Preparación
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
Si existe la necesidad de hacer coincidir caracteres específicos, se puede usar '[]'. Cualquier carácter dentro de '[]' se comparará exactamente una vez.
$ echo [m]acy
macy
$ echo [st][tr]acy
stacy tracy
El []
glob, sin embargo, es más versátil que eso. También permite una coincidencia negativa e incluso gamas coincidentes de caracteres y clases de caracteres. Una coincidencia negativa se logra utilizando !
o ^
como el primer carácter que sigue a [
. Podemos igualar stacy
por
$ echo [!t][^r]acy
stacy
Aquí le estamos diciendo a bash que queremos hacer coincidir solo los archivos que no comienzan con una t
y la segunda letra no es una r
y el archivo termina en acy
.
Los rangos pueden combinarse separando un par de caracteres con un guión ( -
). Cualquier personaje que se encuentre entre esos dos caracteres adjuntos, inclusive, será igualado. Por ejemplo, [rt]
es equivalente a [rst]
$ echo [r-t][r-t]acy
stacy tracy
Las clases de caracteres se pueden hacer coincidir con [:class:]
, por ejemplo, para hacer coincidir los archivos que contienen un espacio en blanco
$ echo *[[:blank:]]*
file with space
Coincidencia de archivos ocultos
Preparación
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
La opción integrada de Bash dotglob permite hacer coincidir archivos y carpetas ocultos, es decir, archivos y carpetas que comienzan con a .
$ shopt -s dotglob
$ echo *
file with space folder .hiddenfile macy stacy tracy
Coincidencia insensible a mayúsculas
Preparación
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
Establecer la opción nocaseglob
coincidirá con el globo de una manera no sensible a mayúsculas y minúsculas
$ echo M*
M*
$ shopt -s nocaseglob
$ echo M*
macy
Comportamiento cuando un glob no coincide con nada.
Preparación
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
En caso de que el globo no coincida con nada, el resultado está determinado por las opciones nullglob
y failglob
. Si ninguno de ellos está configurado, Bash devolverá el globo si no coincide.
$ echo no*match
no*match
Si nullglob
está activado, entonces no se devuelve nada ( null
):
$ shopt -s nullglob
$ echo no*match
$
Si se activa failglob
se failglob
un mensaje de error:
$ shopt -s failglob
$ echo no*match
bash: no match: no*match
$
Tenga en cuenta que la opción failglob
reemplaza a la opción nullglob
, es decir, si están configurados nullglob
y failglob
, entonces, en caso de no coincidir, se devuelve un error.
Globo extendido
Preparación
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
La opción extglob
incorporada de extglob
puede extender las capacidades de correspondencia de un globo
shopt -s extglob
Los siguientes sub-patrones comprenden globos extendidos válidos:
-
?(pattern-list)
: coincide con cero o una aparición de los patrones dados -
*(pattern-list)
: coincide con cero o más apariciones de los patrones dados -
+(pattern-list)
- Coincide con una o más apariciones de los patrones dados -
@(pattern-list)
- Coincide con uno de los patrones dados -
!(pattern-list)
- Coincide con cualquier cosa excepto con uno de los patrones dados
La pattern-list
es una lista de globos separados por |
.
$ echo *([r-t])acy
stacy tracy
$ echo *([r-t]|m)acy
macy stacy tracy
$ echo ?([a-z])acy
macy
La pattern-list
sí puede ser otro globo extendido anidado. En el ejemplo anterior, hemos visto que podemos hacer coincidir tracy
y stacy
con *(rt)
. Este globo extendido en sí mismo puede usarse dentro del globo extendido negado !(pattern-list)
para hacer coincidir macy
$ echo !(*([r-t]))acy
macy
Coincide con cualquier cosa que no comience con cero o más apariciones de las letras r
, s
y t
, lo que deja solo la coincidencia macy
posible.
Coincidencia de expresiones regulares
pat='[^0-9]+([0-9]+)'
s='I am a string with some digits 1024'
[[ $s =~ $pat ]] # $pat must be unquoted
echo "${BASH_REMATCH[0]}"
echo "${BASH_REMATCH[1]}"
Salida:
I am a string with some digits 1024
1024
En lugar de asignar la expresión regular a una variable ( $pat
) también podríamos hacer:
[[ $s =~ [^0-9]+([0-9]+) ]]
Explicación
- La construcción
[[ $s =~ $pat ]]
realiza la coincidencia de expresiones regulares - Los grupos capturados, es decir, los resultados de las coincidencias están disponibles en una matriz denominada BASH_REMATCH
- El índice 0 en la matriz BASH_REMATCH es la coincidencia total
- El índice i'th en la matriz BASH_REMATCH es el i'th grupo capturado, donde i = 1, 2, 3 ...
Obtener grupos capturados de una coincidencia de expresiones regulares contra una cadena
a='I am a simple string with digits 1234'
pat='(.*) ([0-9]+)'
[[ "$a" =~ $pat ]]
echo "${BASH_REMATCH[0]}"
echo "${BASH_REMATCH[1]}"
echo "${BASH_REMATCH[2]}"
Salida:
I am a simple string with digits 1234
I am a simple string with digits
1234