ksh93
und zsh
haben Rückverweis (oder genauer 1 , Verweise auf Capture-Gruppen in der Ersetzung) Unterstützung im Inneren ${var/pattern/replacement}
, nicht 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
(In der mksh
Manpage wird auch erwähnt, dass zukünftige Versionen dies ${KSH_MATCH[1]}
für die erste Erfassungsgruppe unterstützen werden. Ab dem 25.04.2017 noch nicht verfügbar).
Mit können bash
Sie jedoch Folgendes tun:
$ [[ $var =~ -\>[[:space:]]*[^[:space:]]+ ]] &&
printf '%s\n' "${BASH_REMATCH[0]}"
-> r1-ae0-2
Welches ist besser, da es prüft, ob das Muster zuerst gefunden wird.
Wenn die regulären Ausdrücke Ihres Systems \s
/ unterstützen \S
, können Sie auch Folgendes tun:
re='->\s*\S+'
[[ $var =~ $re ]]
Mit erhalten zsh
Sie die volle Leistung von PCREs mit:
$ set -o rematchpcre
$ [[ $var =~ '->\s*\S+' ]] && printf '%s\n' $MATCH
-> r1-ae0-2
Mit zsh -o extendedglob
, siehe auch:
$ printf '%s\n' ${(SM)var##-\>[[:space:]]#[^[:space:]]##}
-> r1-ae0-2
Tragbar:
$ expr " $var" : '.*\(->[[:space:]]*[^[:space:]]\{1,\}\)'
-> r1-ae0-2
Wenn das Muster in der Zeichenfolge mehrmals vorkommt, ändert sich das Verhalten bei all diesen Lösungen. Keiner von ihnen gibt Ihnen jedoch eine durch Zeilenumbrüche getrennte Liste aller Übereinstimmungen wie in Ihrer GNU- grep
basierten Lösung.
Dazu müssten Sie die Schleife von Hand ausführen. Zum Beispiel mit bash
:
re='(->\s*\S+)(.*)'
while [[ $var =~ $re ]]; do
printf '%s\n' "${BASH_REMATCH[1]}"
var=${BASH_REMATCH[2]}
done
Mit zsh
können Sie auf diese Art von Trick zurückgreifen, um alle Übereinstimmungen in einem Array zu speichern:
set -o extendedglob
matches=() n=0
: ${var//(#m)->[[:space:]]#[^[:space:]]##/${matches[++n]::=$MATCH}}
printf '%s\n' $matches
1 Rückverweise bezeichnen häufiger ein Muster, das auf Übereinstimmungen mit einer früheren Gruppe verweist. Beispielsweise entspricht der \(.\)\1
reguläre Basisausdruck einem einzelnen Zeichen, gefolgt von demselben Zeichen (es entspricht ein aa
, nicht ein ab
). Dies \1
ist ein Rückverweis auf diese \(.\)
Erfassungsgruppe im selben Muster.
ksh93
Unterstützt Rückverweise in seinen Mustern ( ls -d -- @(?)\1
listet beispielsweise die Dateinamen auf, die aus zwei identischen Zeichen bestehen), keine anderen Shells. Standard-BREs und -PCREs unterstützen Rückverweise, nicht jedoch Standard-ERE, obwohl einige ERE-Implementierungen dies als Erweiterung unterstützen. bash
‚s [[ foo =~ re ]]
Verwendungen EREs.
[[ aa =~ (.)\1 ]]
wird nicht passen, aber
re='(.)\1'; [[ aa =~ $re ]]
kann, wenn die EREs des Systems dies unterstützen.