¿Cómo puedo usar sed\awk para buscar ciertas líneas dentro de un archivo y luego hacer coincidir todas las líneas posteriores que coincidan con un patrón diferente?

¿Cómo puedo usar sed\awk para buscar ciertas líneas dentro de un archivo y luego hacer coincidir todas las líneas posteriores que coincidan con un patrón diferente?

Encontré un tema similar pero no pude descubrir cómo implementarlo para mi propio uso:

agarrar varias líneas después de una línea objetivo coincidente

Aquí está el problema:

Estoy intentando implementarlo en un proyecto propio pero parece que no puedo hacerlo funcionar. Estoy usando Linux, ¿alguien puede descomponerlo?

Básicamente, lo que intento hacer es revisar un paquete de registros y capturar líneas específicas junto con su pila\detalles. He aquí un ejemplo:

2020-01-20T05:58:19.119Z verbose vpxa[6E21B70] [Originator@6876 sub=PropertyProvider opID=k5cokp1a-928316-auto-jwal-h5:70047736-92-01-84] [CommitChangesAndNotify] Updating cached values
2020-01-20T05:58:19.119Z info vpxa[6E21B70] [Originator@6876 sub=Default opID=k5cokp1a-928316-auto-jwal-h5:70047736-92-01-84] [VpxLRO] -- ERROR task-107599 -- **vm-1178** -- vim.VirtualMachine.reconfigure: vmodl.fault.InvalidArgument:
--> Result:
--> (vmodl.fault.InvalidArgument) {
-->    faultCause = (vmodl.MethodFault) null,
-->    faultMessage = (vmodl.LocalizableMessage) [
-->       (vmodl.LocalizableMessage) {
-->          key = "msg.disk.extendFailure",
-->          arg = (vmodl.KeyAnyValue) [
-->             (vmodl.KeyAnyValue) {

Querré capturar cada línea que contenga "vm-1178" y todas las líneas posteriores que comiencen con "-->" hasta que cambie el patrón, luego comenzar a buscar vm-1178 hasta la próxima vez que esto ocurra, etc.

Espero que tenga sentido. ¡Gracias!

Respuesta1

Prueba esto,

awk '!/^-->/{p=0} /vm-1178/{p=1} p'
  • !/^-->/{p=0}: Establezca var p(como print) en 0 siempre que la línea no comience con -->.
  • /vm-1178/{p=1}: Establezca var p= 1 siempre que la línea coincida /vm-1178/.
  • p: Imprime la línea siempre que psea verdadera (aquí=1)

Respuesta2

Podrías utilizar awkpara ese propósito:

awk 'index($0,"vm-1178")>0 {in_pat=1; print; next} \
in_pat == 1 && $0 ~ /^-->/ {print; next} \
{in_pat=0}' logfile.txt

Contiene tres reglas:

  • La primera regla buscará líneas que contengan el patrón y las imprimirá, además de establecer una bandera interna in_paten 1.
  • La segunda regla establece que todas las líneas posteriores que comiencen con -->también se imprimirán.
  • La tercera regla se utiliza para restablecer esa bandera en la primera línea.noque contenga el patrón o que no comience con -->, de modo que no se imprima nada hasta que se encuentre nuevamente el patrón.

Tenga en cuenta que en la primera regla, indexse utiliza la función en lugar de una coincidencia de RegExp. Esto es para que también puedas buscar patrones que contengan caracteres que tengan un significado especial en expresiones regulares.

Respuesta3

Usando Perl, esto funcionaría:

 perl -ne ' { $t=0 if ( !/^-->/ ); $t=1 if(/vm-1178/); print if($t); }' <filename>

información relacionada