sed con la siguiente línea (opción `+ N`) y la frecuencia (` ~ N`) juntas

Oct 30 2020

Estoy tratando de recuperar 2 líneas de texto con sed, cada 10 líneas (10, 11, 20, 21, 30, 31, ...).

Para las líneas 10 y 11 podría usar sed -n '10,11p' fileo sed -n '10,+1p' file. Y para el rango (líneas 10, 20, 30, ...) sed -n '10,~10p' file. Pero, ¿es posible combinar de alguna manera ambas cosas?

sed -n '10,~10,+1p' file no está trabajando.

Supongo que esto es un duplicado, pero no puedo encontrar ninguna referencia. ¡Gracias!

Respuestas

10 StéphaneChazelas Oct 30 2020 at 17:48

Utilice ADDR1,ADDR2con FIRST~STEPcomo ADDR1y +OFFSETcomo ADDR2, entonces:

$ seq 30 | sed '10~10,+1!d'
10
11
20
21
30

En cualquier caso, tenga en cuenta que ambos ~y +son extensiones GNU no estándar.

Consulte info sed 'line selection'y info sed 'range of lines'en un sistema GNU para obtener más detalles.

POSIXly, usarías:

seq 30 | sed -n '1n;n;n;n;n;n;n;n;n;p;n;p'
7 AdminBee Oct 30 2020 at 17:49

¿Qué tal una awksolución?

awk '(FNR>1) && (FNR%10<2)' file
  • FNRse awkactualiza automáticamente el contador de líneas por archivo
  • Cualquier condición fuera de un "bloque de reglas" ( { ... }) que se evalúe como "verdadera" (y sea la cadena 1) indicará awkque se imprima la línea actual, incluidas todas las modificaciones realizadas hasta ahora.
  • Entonces, (FNR>1) && (FNR%10<2)imprimirá la línea actual, si no es la primera línea, y si el número de línea es un múltiplo entero de 10 (o +1 de dicho múltiplo como máximo). Esto es equivalente a "cada 10 y línea y lo siguiente".
3 RakeshSharma Oct 30 2020 at 23:51

Usando awk podemos hacer lo que se muestra. NR es el número de línea en el lenguaje awk.

$ awk 'NR ~ /.[10]$/'  file

Con sedpodríamos hacer lo que se muestra a continuación, donde incrementamos el espacio de espera hasta que alcancemos el conteo de 10 líneas nuevas.

$ sed -nE 'x /\n{9}/{ z;x;$d
    N;p;D
  }
  s/$/\n/;h
' file
$ perl -ne '$.%10||print($_.<>)' file