ksh93
e zsh
avere il supporto di back-reference (o più precisamente 1 , riferimenti ai gruppi di acquisizione nella sostituzione) all'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
pagina man menziona anche che le versioni future lo supporteranno ${KSH_MATCH[1]}
per il primo gruppo di acquisizione. Non ancora disponibile dal 25/04/2017).
Tuttavia, con bash
, puoi fare:
$ [[ $var =~ -\>[[:space:]]*[^[:space:]]+ ]] &&
printf '%s\n' "${BASH_REMATCH[0]}"
-> r1-ae0-2
Il che è meglio in quanto controlla che il modello sia trovato per primo.
Se il supporto di regexps del tuo sistema \s
/ \S
, puoi anche fare:
re='->\s*\S+'
[[ $var =~ $re ]]
Con zsh
, puoi ottenere tutta la potenza dei PCRE con:
$ set -o rematchpcre
$ [[ $var =~ '->\s*\S+' ]] && printf '%s\n' $MATCH
-> r1-ae0-2
Con zsh -o extendedglob
, vedi anche:
$ printf '%s\n' ${(SM)var##-\>[[:space:]]#[^[:space:]]##}
-> r1-ae0-2
portabile:
$ expr " $var" : '.*\(->[[:space:]]*[^[:space:]]\{1,\}\)'
-> r1-ae0-2
Se ci sono diverse occorrenze del modello nella stringa, il comportamento varierà con tutte quelle soluzioni. Tuttavia, nessuno di loro ti fornirà un elenco separato da una nuova riga di tutte le partite come nella tua GNU-grep
soluzione basata su .
Per fare ciò, dovresti fare il loop a mano. Ad esempio, con bash
:
re='(->\s*\S+)(.*)'
while [[ $var =~ $re ]]; do
printf '%s\n' "${BASH_REMATCH[1]}"
var=${BASH_REMATCH[2]}
done
Con zsh
, potresti ricorrere a questo tipo di trucco per memorizzare tutte le partite in un array:
set -o extendedglob
matches=() n=0
: ${var//(#m)->[[:space:]]#[^[:space:]]##/${matches[++n]::=$MATCH}}
printf '%s\n' $matches
1 riferimenti secondari designano più comunemente un modello che fa riferimento a ciò che è stato abbinato a un gruppo precedente. Ad esempio, l' \(.\)\1
espressione regolare di base corrisponde a un singolo carattere seguito dallo stesso carattere (corrisponde a attivo aa
, non attivo ab
). Questo \1
è un riferimento a quel \(.\)
gruppo di acquisizione nello stesso modello.
ksh93
supporta i riferimenti a ritroso nei suoi modelli (ad esempio ls -d -- @(?)\1
elencherà i nomi dei file costituiti da due caratteri identici), non altre shell. BRE standard e PCRE supportano riferimenti secondari ma non ERE standard, sebbene alcune implementazioni di ERE lo supportino come estensione. bash
's [[ foo =~ re ]]
usi ERE.
[[ aa =~ (.)\1 ]]
non corrisponderà, ma
re='(.)\1'; [[ aa =~ $re ]]
può se gli ERE del sistema lo supportano.