GNU/Linux >> Tutoriales Linux >  >> Linux

¿Duplicar, con unos pequeños cambios, unas pocas líneas en un archivo de texto?

Estoy tratando de averiguar cómo replicar un solo rango de líneas en un archivo de texto. El rango comienza con una línea que es única en el archivo, pero termina con una línea que puede existir en varios lugares del archivo.

Aquí hay una entrada de ejemplo que necesito procesar:

I have no imagination
so this sample text will
Common
be boring. But it does
demonstrate the problem
I am trying to solve.
Common
Hi mom!
This is a unique line.
And here is some more
text that should be copied
as well.
Common
Followed by text that should
not be copied.

Las líneas que necesito duplicar y modificar están en negrita para señalarlas aquí.

La salida que necesito es:

I have no imagination
so this sample text will
Common
be boring. But it does
demonstrate the problem
I am trying to solve.
Common
Hi mom!
This is a changed line.
And here is different more
text that should be copied
as well.
Common
This is a unique line.
And here is some more
text that should be copied
as well.
Common
Followed by text that should
not be copied.

El resultado adicional está en negrita para que quede claro.

Necesito obtener el rango de líneas que comienzan con la línea:

This is a unique line

y terminando con la línea:

Common

Ese rango de líneas debe insertarse justo antes del rango de líneas original. La copia del rango de líneas correspondiente deberá modificarse ligeramente.

La línea "Común" que finaliza el rango puede aparecer en muchos lugares dentro del archivo.

Se me ocurrió un awk funcional guión, pero parece mucho más complicado de lo que debe ser. Mi awk las habilidades son inexistentes.

/This is a unique line/{flag=1}
/Common/{
    if (flag > 0) {
        n=m;
        sub("some","different",n);
        sub("unique","changed",n);
        print n "\n" $0 "\n" m;
        m=""
    };
    flag=0
};
flag{
    if (length(m) > 0) {
        m=m "\n" $0
    } else {
        m=$0
    }
}
!flag{ print }

¿Hay una forma más limpia y menos detallada de implementar esto? Estoy abierto a otras opciones además de awk . Solo necesita ser un comando estándar disponible en macOS.

Respuesta aceptada:

awk '/This is a unique line/,/Common/{
   H = H RS $0
   if ( $0 ~ /Common/ ) {
      g = H
      sub("\n","",g)
      sub("some","different",g)
      sub("unique","changed",g)
      $0 = g H
   } else { next }
}1'   inputfile

Aquí está el sed código (lo mostré en la sección Respuesta) traducido a awk .

Tenga en cuenta que, con el código que tiene, asume la responsabilidad de ACTIVAR/DESACTIVAR el awk bandera variable para realizar un seguimiento de las líneas. Pero mientras que, awk ya lo hace bajo el capó exactamente lo mismo cuando usas su range operador ,


Linux
  1. Cat ¿Línea X a Línea Y en un archivo enorme?

  2. ¿Cómo eliminar líneas duplicadas dentro de un archivo de texto?

  3. ¿Insertar nuevas líneas con valores faltantes (na)?

  4. ¿Eliminar eficientemente el primer par de líneas de un archivo de texto?

  5. ¿Cómo se reemplaza el texto similar a sed con python?

Comando Diff en Linux con ejemplos

Manipulación de texto en la línea de comando con grep

Cómo encontrar las líneas más largas en un archivo en Linux

¿Seguimiento de los cambios de Crontab con Git?

Cómo contar líneas en un archivo en UNIX/Linux

texto de eco con nueva línea en bash