awk comenzando desde un texto fijo, hasta la primera línea en blanco

awk comenzando desde un texto fijo, hasta la primera línea en blanco

Estoy intentando conectar algo que devuelva solo el primer "párrafo" o "sección" separado por una línea en blanco. Pensé que podría usar awkor sedpara obtener un rango según otras respuestas, pero no parece funcionar.

$ cat txt
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.9.1-0ubuntu0.1
Supported: 3y

Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.4-0ubuntu1
Supported: 3y

$ cat txt |awk '/^Package:/,/^$/'
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.9.1-0ubuntu0.1
Supported: 3y

Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.4-0ubuntu1
Supported: 3y

¿No debería devolver sólo la primera "sección"? (según: Grep comenzando desde un texto fijo, hasta la primera línea en blanco y https://www.unix.com/shell-programming-and-scripting/148692-awk-script-match-pattern-till-blank-line.html)

  • Si uso grep -ve ^$las líneas en blanco, se eliminan, por lo que no hay caracteres especiales.
  • Si intento extraer una parte diferente, obtengo las partes de ambas "secciones":

    $ cat txt |awk '/^Package:/,/^Version:/'
    Package: plasma-desktop
    Architecture: amd64
    Version: 4:5.12.9.1-0ubuntu0.1
    Package: plasma-desktop
    Architecture: amd64
    Version: 4:5.12.4-0ubuntu1
    
  • Si uso sed -n '/^Package:/,/^$/p'o sed -n '/^Package:/,/^Version:/p'obtengo los mismos resultados que el equivalente awk.

¿Cómo consigo awko seddetengo después de la primera aparición?

Respuesta1

Esta es exactamente la razón por la que awk tiene un modo de párrafo:

$ awk -v RS= 'NR==1' file
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.9.1-0ubuntu0.1
Supported: 3y

e imprimir el segundo registro es solo el cambio obvio de NR==1a NR==2:

$ awk -v RS= 'NR==2' file
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.4-0ubuntu1
Supported: 3y

Por cierto, nunca use expresiones de rango: hacen que el código para problemas triviales sea un poco más breve que usar una bandera, pero luego, si sus requisitos cambian en lo más mínimo, requerirán una reescritura completa o condiciones duplicadas. Entonces, cada vez que desee usar /begin/,/end/sed o awk, use /begin/{f=1} f{print} /end/{f=0}awk en su lugar y eso le brinda MUCHO más control sobre cuándo/cómo imprimir las líneas de inicio/final, etc.

Respuesta2

En /begin/,/end/, las "banderas de acción" se activan cada vez que /begin/se encuentra una coincidencia y se desactivan cuando /end/se encuentra una coincidencia. También se imprimen las líneas de límite con "comienzo" y "fin".

Las consecuencias de su entrada son (las líneas impresas tienen un comentario después en los siguientes ejemplos):

  • Con '/^Package:/,/^$/':
    Package: plasma-desktop        #TURN ON
    Architecture: amd64            #
    Version: 4:5.12.9.1-0ubuntu0.1 #
    Supported: 3y                  #
                                   #TURN OFF
    Package: plasma-desktop        #TURN ON
    Architecture: amd64            #
    Version: 4:5.12.4-0ubuntu1     #
    Supported: 3y                  #
  • Con '/^Package:/,/^Version:/':
    Package: plasma-desktop        #TURN ON
    Architecture: amd64            #
    Version: 4:5.12.9.1-0ubuntu0.1 #TURN OFF
    Supported: 3y

    Package: plasma-desktop        #TURN ON
    Architecture: amd64            #
    Version: 4:5.12.4-0ubuntu1     #TURN OFF
    Supported: 3y

Para imprimir sólo el párrafo que comienza en "Paquete:" puedes escribir

sed -ne '/^$/q' -e '/^Package:/,$p' file

seddeja de procesar el archivo tan pronto como encuentra una línea en blanco debido a /^$/q.

Con awk:

awk '/^$/{exit};/^Package:/,0' file

Respuesta3

Como comentado porcuasimodo

/begin/,/end/obtiene líneas que coinciden con esas expresiones regulares, incluidas las líneas de límite. comenzar activa la impresión y finalizar la desactiva. La línea justo después de la línea en blanco vuelve a activar la impresión, porque también la tiene Package:.

Me di cuenta de que puedo usar sedy cambiar /begin/a 0y comenzará desde el principio. Como sólo hay un comienzo, sólo coincidirá una vez.

$ cat txt |sed -n '0,/^$/p'
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.9.1-0ubuntu0.1
Supported: 3y

información relacionada