¿Puede GNU Grep generar un grupo seleccionado?


47

¿Es posible usar GNU grep para obtener un grupo coincidente de una expresión?

Ejemplo:

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

Lo que generaría "'bar'". Pero me gustaría obtener solo "bar", sin tener que enviarlo a través de grep una vez más (es decir, obtener el grupo coincidente). ¿Es eso posible?

Respuestas:


50

Puedes usar sedpara esto. En BSD sed:

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

O, sin la -Eopción:

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

Esto no funciona para la entrada multilínea. Para eso necesitas:

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

Gracias, se había olvidado de sed. Pero para aclarar, sed no toma el argumento -E ..
Torandi

Hm, lo hace en mi máquina (Mac OS X). Tras un examen más detallado, en la página del manual: "Las opciones -E, -a y -i son extensiones de FreeBSD no estándar y pueden no estar disponibles en otros sistemas operativos".
jtbandes

1
-r parece eso para mí.
Torandi el

1
@jtbandes: No necesita las características extendidas para esta expresión. Solo necesito 3 caracteres de escape para ( ) +usar \( \) \+: Esto es efectivamente lo mismo:sed "s/.*'\([^']\+\)'.*/\1/"
Peter.O

2
Esto no funciona para la entrada multilínea. Para eso necesitas: sed -n "s/.*'\([^']\+\)'.*/\1/p"
phreakhead

28

Si bien grep no puede generar un grupo específico, puede usar aserciones anticipadas y subyacentes para lograr lo que busca:

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


8
grep -Pno está disponible en todas las plataformas. Pero si es así, usar mirar hacia adelante / atrás es una muy buena manera de resolver el problema.
Sébastien

1
¿Es grep inteligente con las afirmaciones retrospectivas? ¿Cómo funciona con largas miradas atrás? ¿Está integrando los look-behinds en algún tipo de "árbol de sufijos" con el resto de la expresión regular?
Ross Rogers

3

Puede usar \Kpara restablecer y descartar el texto de coincidencia de la izquierda junto con una búsqueda anticipada que no se agrega al texto de coincidencia:

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

GNU grep solamente.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.