unix sed – Sed para imprimir solo la primera coincidencia de patrón de la línea

Pregunta:

Tengo algunos datos como

<td><a href="data1">abc</a> ... <a href="data2">abc</a> ... <a href="data3">abc</a>

(Se referiría a la línea anterior como data en el código a continuación)

Necesito data1 entre el primer " y " así que lo hago

echo 'data' | sed 's/.*"\(.*\)".*/\1/'

pero me devuelve la última cadena entre " y " siempre, es decir, en este caso me devolvería data3 en lugar de data1

Para obtener data1 , termino haciendo

echo 'data' | sed 's/.*"\(.*\)".*".*".*".*".*/\1/'

¿Cómo obtengo data1 sin tanta redundancia en sed

Respuesta:

El .* En el patrón de expresiones regulares es codicioso, coincide con una cadena tan larga como sea posible, por lo que las comillas que coincidan serán las últimas.

Dado que el separador es solo un carácter aquí, podemos usar un grupo de corchetes invertidos para hacer coincidir cualquier cosa que no sea una cita, es decir, [^"] , y luego lo repite para hacer coincidir una cantidad de caracteres que no son comillas.

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

Otra forma sería simplemente eliminar todo hasta la primera cita, luego eliminar todo a partir de la primera cita (nueva):

$ echo '... "foo" ... "bar" ...' | sed 's/^[^"]*"//; s/".*$//'
foo

En las expresiones regulares de Perl, los especificadores * y + se pueden convertir en no codiciosos agregando un signo de interrogación, entonces .*? haría cualquier cosa, pero la menor cantidad de caracteres / bytes como sea posible.

Leave a Comment

Your email address will not be published. Required fields are marked *

web tasarım