
Tengo un archivo prova.txt
como este:
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4
extra1
extra2
bla
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
extra2
bla
bla
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131
y necesito pasar de "Empezar a agarrar aquí" a la primera línea en blanco. La salida debería ser así:
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131
Como puede ver, las líneas después de "Empezar a capturar aquí" son aleatorias, por lo que el indicador -A -B grep no funciona:
cat prova.txt | grep "Start to grab from here" -A 15 | grep -B 15 "^$" > output.txt
¿Puedes ayudarme a encontrar una manera de capturar la primera línea que se capturará (como "Empezar a capturar desde aquí"), hasta que quede una línea en blanco? No puedo predecir cuántas líneas aleatorias tendré después de "Empezar a capturar desde aquí".
Se agradece cualquier solución compatible con Unix (grep, sed, awk es mejor que perl o similar).
EDITADO: después de la brillante respuesta de @john1024, me gustaría saber si es posible:
1° ordenar el bloque (según Comience a tomar desde aquí: 1 luego 1 luego 2)
2° eliminar 4 líneas (alfabéticamente aleatorias) fix1,fix2,fix3,fix4 pero siempre son 4
3° eventualmente elimine los engaños aleatorios, como el comando sort -u
El resultado final debería ser así:
# fix lines removed - match 1 first time
Start to grab from here: 1
random1
random2
random3
random4
#fix lines removed - match 1 second time
Start to grab from here: 1
#random1 removed cause is a dupe
random22131
#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561
o
# fix lines removed - match 1 first time and the second too
Start to grab from here: 1
random1
random2
random3
random4
#random1 removed cause is a dupe
random22131
#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561
La segunda salida es mejor que la primera. Se necesita algún otro comando mágico de Unix.
Respuesta1
Usando awk
Intentar:
$ awk '/Start to grab/,/^$/' prova.txt
Start to grab from here: 1
random1
random2
random3
random4
Start to grab from here: 2
random1546
random2561
Start to grab from here: 3
random45
random22131
/Start to grab/,/^$/
define un rango. Comienza con cualquier línea que coincida Start to grab
y termina con la primera línea vacía, ^$
que sigue.
Usando sed
Con una lógica muy similar:
$ sed -n '/Start to grab/,/^$/p' prova.txt
Start to grab from here: 1
random1
random2
random3
random4
Start to grab from here: 2
random1546
random2561
Start to grab from here: 3
random45
random22131
-n
le dice a sed que no imprima nada a menos que se lo solicitemos explícitamente. /Start to grab/,/^$/p
le dice que imprima cualquier línea en el rango definido por /Start to grab/,/^$/
.
Respuesta2
Estoy publicando una solución alternativa, ya que puede resultar útil para los casos de uso de algunas personas. Esta solución no cumple exactamente con los requisitos establecidos; para conocer la mejor solución, consulte la respuesta de @John1024.
Puede usar awk con el separador de registros configurado en una cadena vacía; awk las interpretará como nuevas líneas en blanco:
$ awk '/Start/' RS= prova.txt
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131
Esta versión no conserva las nuevas líneas en blanco en la salida. También mostrará el contexto antes del partido, si está presente. Este comportamiento puede ser muy útil al buscar algo en un archivo y desea ver el bloque delimitado por nueva línea del que forma parte, por ejemplo:
$ awk '/random1546/' RS= prova.txt
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
Por ejemplo, esto me resulta útil cuando busco cosas en ini
archivos.