ksh93
y zsh
tener respaldo de referencia (o más exactamente 1 , referencias a grupos de captura en el reemplazo), soporte interno ${var/pattern/replacement}
, no bash
.
ksh93
:
$ var='Blah: -> r1-ae0-2 / [123]'
$ printf '%s\n' "${var/*@(->*([[:space:]])+([^[:space:]]))*/\1}"
-> r1-ae0-2
zsh
:
$ var='Blah: -> r1-ae0-2 / [123]'
$ set -o extendedglob
$ printf '%s\n' "${var/(#b)*(->[[:space:]]#[^[:space:]]##)*/$match[1]}"
-> r1-ae0-2
(La mksh
página de manual también menciona que las versiones futuras lo admitirán ${KSH_MATCH[1]}
para el primer grupo de captura. Todavía no está disponible a partir del 25/04/2017).
Sin embargo, con bash
, puedes hacer:
$ [[ $var =~ -\>[[:space:]]*[^[:space:]]+ ]] &&
printf '%s\n' "${BASH_REMATCH[0]}"
-> r1-ae0-2
Lo cual es mejor ya que comprueba que el patrón se encuentra primero.
Si la expresión regular de su sistema es compatible con \s
/ \S
, también puede hacer:
re='->\s*\S+'
[[ $var =~ $re ]]
Con zsh
, puede obtener toda la potencia de los PCRE con:
$ set -o rematchpcre
$ [[ $var =~ '->\s*\S+' ]] && printf '%s\n' $MATCH
-> r1-ae0-2
Con zsh -o extendedglob
, vea también:
$ printf '%s\n' ${(SM)var##-\>[[:space:]]#[^[:space:]]##}
-> r1-ae0-2
Portablemente:
$ expr " $var" : '.*\(->[[:space:]]*[^[:space:]]\{1,\}\)'
-> r1-ae0-2
Si hay varias ocurrencias del patrón en la cadena, el comportamiento variará con todas esas soluciones. Sin embargo, ninguno de ellos le dará una lista separada por líneas nuevas de todas las coincidencias como en su grep
solución basada en GNU .
Para hacer eso, deberías hacer el bucle a mano. Por ejemplo, con bash
:
re='(->\s*\S+)(.*)'
while [[ $var =~ $re ]]; do
printf '%s\n' "${BASH_REMATCH[1]}"
var=${BASH_REMATCH[2]}
done
Con zsh
, puedes recurrir a este tipo de truco para almacenar todas las coincidencias en una matriz:
set -o extendedglob
matches=() n=0
: ${var//(#m)->[[:space:]]#[^[:space:]]##/${matches[++n]::=$MATCH}}
printf '%s\n' $matches
1 las referencias inversas generalmente designan un patrón que hace referencia a lo que coincidió con un grupo anterior. Por ejemplo, la \(.\)\1
expresión regular básica coincide con un solo carácter seguido de ese mismo carácter (coincide con aa
, no con ab
). Esa \1
es una referencia a ese \(.\)
grupo de captura en el mismo patrón.
ksh93
admite referencias posteriores en sus patrones (por ejemplo ls -d -- @(?)\1
, enumerará los nombres de archivo que constan de dos caracteres idénticos), no otros shells. Los BRE y PCRE estándar admiten referencias posteriores pero no ERE estándar, aunque algunas implementaciones de ERE lo admiten como una extensión. bash
's [[ foo =~ re ]]
usa ERE.
[[ aa =~ (.)\1 ]]
no coincidirá, pero
re='(.)\1'; [[ aa =~ $re ]]
mayo si los ERE del sistema lo admiten.