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 "Comenzar 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 "Comenzar a agarrar aquí" son aleatorias, por lo que el indicador grep -A -B no funciona:
cat prova.txt | grep "Start to grab from here" -A 15 | grep -B 15 "^$" > output.txt
¿Me pueden ayudar a encontrar una manera de atrapar la primera línea que se tomará (como "Comenzar a tomar desde aquí"), hasta una línea en blanco. No puedo predecir cuántas líneas aleatorias tendré después de "Comenzar a tomar desde aquí".
Cualquier solución compatible con Unix es apreciada (grep, sed, awk es mejor que perl o similar).
EDITADO: después de una respuesta brillante de @ john1024, me gustaría saber si es posible:
1 ° ordenar el bloque (de acuerdo a Comenzar a agarrar desde aquí: 1 luego 1 y luego 2)
2 ° elimina 4 líneas (alfabéticamente aleatorias) fix1, fix2, fix3, fix4 pero siempre son 4
3 ° eventualmente elimina duplicados aleatorios, como el comando sort -u
La salida 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.
fuente
Respuestas:
Usando awk
Tratar:
/Start to grab/,/^$/
define un rango Comienza con cualquier línea que coincidaStart to grab
y termina con la primera línea vacía^$
, que sigue.Usando sed
Con una lógica muy similar:
-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/,/^$/
.fuente
Estoy publicando una solución alternativa, ya que puede ser útil para los casos de uso de algunas personas. Esta solución no cumple exactamente con los requisitos establecidos, para la mejor solución vea la respuesta de @ John1024.
Puede usar awk con el Separador de registros establecido en una cadena vacía, awk los interpretará como líneas nuevas en blanco:
Esta versión no conserva las nuevas líneas en blanco en la salida. También mostrará 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 de nueva línea del que forma parte, por ejemplo:
Por ejemplo, esto me resulta útil al buscar cosas en los
ini
archivos.fuente