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 ,