Realizar operaciones sed en números de línea dados


8

Me pregunto si hay una manera simple de operar en ciertas líneas con números de línea preasignados.

Digamos que quiero generar las líneas 1, 7, 14 y 16 de un archivo, simplemente puedo hacer

sed -n '1p;7p;14p;16p' input_file

pero esto se vuelve más complicado cuando la operación no es solo imprimir, y no quiero escribir el mismo comando largo 4 veces (y sí, sé que puedo construir este comando sed largo sustituyendo la misma variable bash 4 veces, pero eso no es lo suficientemente ideal ...), es decir

sed -n '1{long_command};7{long_command};14{long_command};16{long_command}' input_file

¿Hay alguna manera de hacer la operación en estas líneas específicas de mi archivo? Estoy esperando algo como

sed -n '1,7,14,16p'

que ciertamente no funcionará en la forma actual.

Cualquier ayuda será apreciada. "No, no es posible." con explicaciones es también una respuesta que aceptaré.


Es fácil conawk
— RomanPerekhrest

Respuestas:


11

Puedes usar ramas:

sed '
  1b1
  7b1
  14b1
  16b1

  # for the rest to be left alone, branch off (or delete them with "d"):
  b

  :1
  long_command'

(tenga en cuenta que también puede agregar algunos 20,25b1rangos de línea o /re/b1incluir líneas que coincidan con re).

O podrías usar awk:

awk 'NR == 1 || NR == 7 || ... {stuff}'

O usando un hash:

awk -v l=1,7,14,16 '
  BEGIN{split(l, a, ","); for (i in a) lines[a[i]]}

  NR in lines {stuff}'

(o BEGIN{lines[1]lines[7]lines[14]lines[16]}si no hay demasiados)


Gracias, nunca pensé en ramas ... Simplemente parece ser la herramienta ideal para usar en este caso.
— Weijun Zhou

¿Cómo utilizar ramas como esta en sed con un patrón de búsqueda? como decir que quiero emparejar o eliminar un patrón después de la enésima línea?
— qodeninja

3

Simplemente invierta su selección y elimínela:

sed '2,6d;8,13d;15d;17,$d;long_command'

Esta también es una buena solución, aunque un poco más difícil para manejar números de línea que se leen desde la entrada estándar, por ejemplo.
— Weijun Zhou

1

Primera variante:

Puedes usar este truco:

sed -nf <(printf '%dp\n' 1 7 14 16)

-f script-file : agrega el contenido del script-file a los comandos que se ejecutarán.

Pruebas

seq 1 20 | sed -nf <(printf '%dp\n' 1 7 14 16)

Salida

1
7
14
16

Segunda variante:

Al principio, el auxiliar sedse usa para filtrar solo las líneas necesarias del archivo, luego estas líneas se canalizan a la principal sedcon el comando largo.

sed -n '1p; 7p; 14p; 16p' input.txt | sed 'long command'
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.