Cómo eliminar una sola línea entre dos líneas

Cómo eliminar una sola línea entre dos líneas

Tengo millones de registros en un archivo que se parece a este

echo "NEW Cell"
grep "2553,24" out.2A25.20090308.64436.7.HDF.txt.text = 22.58   5.39  82.09 237
echo "NEW Cell"
grep "2555,20" out.2A25.20090308.64436.7.HDF.txt.text = 24.72   5.58  82.05 237
echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75   5.62  82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34   5.58  82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2   5.57  82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69   5.62  82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74   5.60  82.30 120
echo "NEW Cell"
grep "2560,24" out.2A25.20090308.64436.7.HDF.txt.text = 19.38   5.54  82.30 170
echo "NEW Cell"

Ahora quiero eliminar la línea con "grep" con la condición de que sea la ÚNICA línea entre las líneas que contienen "Nueva celda". Es decir, si hay una línea grep entre las nuevas celdas, entonces esta línea debe eliminarse.

¿Como hacer esto?

Mi salida debería verse así,

echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75   5.62  82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34   5.58  82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2   5.57  82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69   5.62  82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74   5.60  82.30 120

Respuesta1

AWKsolución:

awk 'NR==n{ if (/NEW Cell/) { f=0 } else print r ORS gr }
     /NEW Cell/{ f=1; n=NR+2; r=$0; next }
     f && n-NR==1 && /^grep /{ gr=$0; next }1' file
  • /NEW Cell/{ f=1; n=NR+2; r=$0; next }- al encontrar la línea conNEW Cell

    • f=1= establecer bandera activaf=1
    • n=NR+2- establecer ncomo número máximo de las siguientes líneas a procesar (2 líneas siguientes)
    • r=$0- capturando la línea
    • next- saltar al siguiente registro
  • f && n-NR==1 && /^grep /- al encontrar la segunda línea (asegurada por n-NR==1) que comienza con grepla palabra clave

    • gr=$0; next- capturar greplínea y saltar al siguiente (tercer) registro
  • NR==n{ if (/NEW Cell/) { f=0 } else print r ORS gr }- al encontrar la tercera línea crucial (asegurada por NR==n)

    • if (/NEW Cell/) { f=0 }- si la tercera línea en la sección procesada contiene NEW Cell- restablecer el procesamiento actual con f=0(se omiten todas las líneas capturadas anteriormente)
    • else print r ORS gr- de lo contrario, imprima todas las líneas capturadas previamente

La salida:

echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75   5.62  82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34   5.58  82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2   5.57  82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69   5.62  82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74   5.60  82.30 120

Respuesta2

Solución compacta con sed:

sed '/NEW Cell/!{H;d;};x;/\n.*\n/!d'

Si la línea no contiene, NEW Cellejecute Hpara agregar la línea al espacio de retención y ddetener el procesamiento de esa línea.

Por lo tanto, los comandos adicionales solo se aplican a NEW Celllas líneas: el xespacio de patrón y el espacio de espera se intercambian, por lo que la línea ahora está en el espacio de espera y se pueden agregar más líneas, mientras que el espacio de patrón contiene todo lo agregado a la última NEW Celllínea. Su requisito es que haya más de una línea entre NEW Celllíneas, por lo que debe haber al menos dos nuevas líneas en el espacio del patrón. Si no, elimínelo sin salida: /\n.*\n/!d.

Respuesta3

Con rudimentarios awk...

La versión 1 solo eliminará greplas líneas que siguen la descripción del OP:

awk '/^grep/ { if (f) { if (length(s) > 0) { print s; s="" } print } \
     else { f=1; s=$0 } } ! /^echo/ { print; f=0 } \
     ! /^echo/ && ! /^grep/ { print }' inputfile

La versión 2 eliminará greplas líneas individuales, así como la línea anterior que no es grep y que sigue la salida de muestra de OP:

awk '/^grep/ { if (f) { if (length(s) > 0) { print s; s="" } print } \
    else { f=1; s=s "\n" $0 } } /^echo/ { s=$0; f=0 } \
    ! /^echo/ && ! /^grep/ { print }' inputfile

Forma legible de la versión 2...

/^grep/ { 
   if (found) {  # found==true : already encountered first grep line
       if (length(save) > 0) {
          print save
          save=""
       }
       print
   } else {
       found=1
       save=save "\n" $0  # append the first grep line to saved preceding line
   }
}

/^echo/ { 
    save=$0  # save this line for possible later printing
    found=0
}

# print anything else
! /^echo/ && ! /^grep/ { print }

Este formulario largo se puede ejecutar colocando el contenido en un archivo (por ejemplo awkfile, ) y awk -f awkfile inputfile.

Respuesta4

gawk '
/\n.+\n/{
    printf("%s%s", RS, $0);
}' RS='echo "NEW Cell"\n' input.txt

Explicación:

  1. RS='echo "NEW Cell"\n'- RSes el separador de registros de entrada, por defecto una nueva línea. Ahora se cambia a echo "NEW Cell"\n, por lo tanto, se eliminarán todas las apariciones de esta cadena y todos los caracteres entre ellas se convertirán en el elemento de registro.
  2. /\n.+\n/{- sólo para registros que coincidan con este patrón - nueva línea, uno o más caracteres, nueva línea. Por lo tanto, solo coincide con registros de varias líneas, el registro de una sola línea no coincide porque solo tiene un archivo \n.
  3. printf("%s%s", RS, $0);- imprime el registro, precedido por RS( echo "NEW Cell"\n).

Producción

echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75   5.62  82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34   5.58  82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2   5.57  82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69   5.62  82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74   5.60  82.30 120

información relacionada