¿Cómo detener un script sed si encuentra dos patrones de inicio antes de un patrón final?

Necesito encontrar todas las revisiones en un vuelco de subversión que tenga cambios en pom.xml.

Estoy usando svndumptool para imprimir con éxito las revisiones, y luego sed para filtrar esos hallazgos.

Puedo hacer coincidir el número de revisión como el inicio, pero necesito poder descartarlo si encuentro un segundo inicio coincidente antes de encontrar una parada.

Aquí está el command que estoy usando:

svnDumpTool=~/path/to/svndumptool.py target=specificSvn.dump # use svndumptool to read the svnlog from target to stdin | # sed then matches start -r[0-9], such as -r103, ends on pom.xml # then networkingirects stdout > to a log file for this target $svnDumpTool log $target -v | sed -n '/r[0-9]/,/pom.xml/p' > $target.log 

Teniendo en count un logging de algo como esto:

  -r0 | ... | ... Changed paths: none; initialization of the repo; not my match -r1 | ... | ... Changed paths: ... not my matches here -------- -r2 | ... | ... Changed paths: ... nor here -------- -r3 | ... | ... Changed paths: pom.xml -------- -r4 | ... | ... Changed paths: pom.xml -------- -r5 | ... | ... Changed paths: ... changes may or may not be here -------- 

Aquí están los resultados.

  1. En el primer pase, obtengo más de lo que quiero:

    • Conseguiré una coincidencia al inicio de -r0,
    • Una coincidencia al final de pom.xml desde -r3,
    • Que imprime todo de inicio a fin, incluyendo -r0, -r1 y -r2:

       -r0 | ... | ... Changed paths: none; initialization of the repo; not my match -r1 | ... | ... Changed paths: ... not my matches here -------- -r2 | ... | ... Changed paths: ... nor here -------- -r3 | ... | ... Changed paths: pom.xml 
  2. En el segundo pase, obtengo exactamente lo que quiero:

    • Conseguiré una coincidencia al inicio de -r4,
    • Una coincidencia al final de pom.xml desde -r4:

       -r4 | ... | ... Changed paths: pom.xml 

Entonces, lo que creo que debo hacer es:

  1. Si encuentro un comienzo,
  2. Y encuentro otra expresión que coincide con el inicio antes de encontrar una expresión que coincida con el final,
  3. Entonces tirar el primer comienzo; de lo contrario imprima.

Creo que esta publicación podría tener mi respuesta, pero cualquier bash que haya intentado ha fallado.

EDITAR: Autocorrección me consiguió, y enumeré incorrectamente el resultado como "Pom.xml" cuando debería ser "pom.xml".

Esto podría funcionar para usted (GNU sed):

 sed '/-r[0-9]/{h;d};H;/Pom.xml/!d;x' file 

Esto almacena las líneas que comienzan con -r[0-9] y aquellas posteriores en el espacio de espera, sobrescribiendo las que ya están en el HS con las más nuevas hasta una línea que contiene Pom.xml cuando imprime todas esas líneas.

Yo usaría Perl para este tipo de cosas:

 #!/usr/bin/env perl use strict; use warnings; my $svnDumpTool = '~/path/to/svndumptool.py'; my $target = 'specificSvn.dump'; my @rev = split /----*/, `$svnDumpTool log $target -v`; foreach (@rev) { print if m/-r\d+[\s\S]*?Pom\.xml/; } 

Sed es la herramienta equivocada aquí. Puedes hacerlo (sed es Turing-completo), pero será ilegible.

Awk es probable que funcione mucho mejor. No estoy familiarizado con svndumptool ; suponiendo que coloca el separador -------- entre revisiones, puede usarlo como el separador de loggings. GNU awk permite expresiones regulares como el separador de loggings.

 awk -v RS='--------\n' -v ORS='--------\n' ' /^pom\.xml$/ { print } '