GNU Grep può generare un gruppo selezionato?


47

È possibile usare GNU grep per ottenere un gruppo corrispondente da un'espressione?

Esempio:

echo "foo 'bar'" | grep -oE "'([^']+)'"

Che produrrebbe "'bar'". Ma vorrei ottenere solo "bar", senza doverlo inviare tramite grep ancora una volta (cioè ottenere il gruppo abbinato). È possibile?

Risposte:


50

Puoi usarlo sedper questo. Su BSD sed:

echo "foo 'bar'" | sed -E "s/.*'([^']+)'.*/\\1/"

Oppure, senza l' -Eopzione:

sed "s/.*'\([^']\+\)'.*/\1/"

Questo non funziona per l'input multilinea. Per questo è necessario:

sed -n "s/.*'\([^']\+\)'.*/\1/p"

Grazie, mi ero dimenticato di sed. Ma per chiarire, sed non
accetta

Hm, lo fa sul mio computer (Mac OS X). Dopo un ulteriore esame, nella pagina man: "Le opzioni -E, -a e -i sono estensioni di FreeBSD non standard e potrebbero non essere disponibili su altri sistemi operativi."
jtbandes

1
-r sembra a quello per me.
Torandi,

1
@jtbandes: Non hai bisogno delle funzionalità estese per questa espressione .. Ho solo bisogno di 3 caratteri di escape per l' ( ) +uso \( \) \+: questo è effettivamente lo stesso:sed "s/.*'\([^']\+\)'.*/\1/"
Peter.O

2
Questo non funziona per l'input multilinea. Per questo è necessario: sed -n "s/.*'\([^']\+\)'.*/\1/p"
phreakhead

28

Mentre grep non può generare un gruppo specifico, puoi usare lookahead e dietro asserzioni per ottenere ciò che desideri:

echo "foo 'bar'" | grep -Po "(?<=')[^']+(?=')"


8
grep -Pnon è disponibile su tutte le piattaforme. Ma se lo è, usare lookahead / behind è un modo molto carino di risolvere il problema.
Sébastien,

1
Grep è intelligente con le asserzioni look-behind? Come si comporta con lunghi look-behind? Sta integrando i look-behind in una sorta di "suffisso" con il resto della regex?
Ross Rogers,

3

Puoi usare \Kper ripristinare e scartare il testo della corrispondenza della mano sinistra insieme a un lookahead che non viene aggiunto al testo della corrispondenza:

$ echo "foo 'bar'" | grep -oP "'\K[^']+(?=')"
bar

Solo GNU grep.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.