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
AWK
solució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
- establecern
como número máximo de las siguientes líneas a procesar (2 líneas siguientes)r=$0
- capturando la líneanext
- saltar al siguiente registro
f && n-NR==1 && /^grep /
- al encontrar la segunda línea (asegurada porn-NR==1
) que comienza congrep
la palabra clavegr=$0; next
- capturargrep
lí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 porNR==n
)if (/NEW Cell/) { f=0 }
- si la tercera línea en la sección procesada contieneNEW Cell
- restablecer el procesamiento actual conf=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 Cell
ejecute H
para agregar la línea al espacio de retención y d
detener el procesamiento de esa línea.
Por lo tanto, los comandos adicionales solo se aplican a NEW Cell
las líneas: el x
espacio 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 Cell
línea. Su requisito es que haya más de una línea entre NEW Cell
lí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á grep
las 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á grep
las 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:
RS='echo "NEW Cell"\n'
-RS
es el separador de registros de entrada, por defecto una nueva línea. Ahora se cambia aecho "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./\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
.printf("%s%s", RS, $0);
- imprime el registro, precedido porRS
(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