Tengo un archivo de registro de 8 Gb (registro de producción de Rails). Necesito cortarlo entre algunas fechas (líneas). ¿Qué comando podría usar para hacer esto?
sed
lo harás fácilmente.
Tengo un archivo de registro de 8 Gb (registro de producción de Rails). Necesito cortarlo entre algunas fechas (líneas). ¿Qué comando podría usar para hacer esto?
sed
lo harás fácilmente.
Respuestas:
Algo como
sed '1,/last date prior to chunk/d;/first date after chunk/,$d' logfile | tee cut-log | less
tee cut-log
le permite ver en pantalla lo que se está poniendo en el archivo cut-log
.
EDITAR:
Para satisfacer los exigentes estándares de fred.bear, aquí hay una solución sed (aunque podría decirse que la solución awk es mucho más bonita):
b=BB; e=EE ;echo -e "AA\nAA\nBB\nBB\nCC\nCC\nDD\nDD\nEE\nEE\nFF\nFF" | sed -n ":b;/$b/b p;n;b b;:p;p;n;/$e/b e;b p;:e;p;n;/$e/b e;q"
sed
puede igualar la awk
velocidad, y en realidad fue un poco más rápido.
Para imprimir todo entre FOO y BAR inclusive, intente:
$ sed -n '/FOO/,/BAR/p' file.txt
Esto hará lo que desee ...
Se muestran las fechas de parámetros incluidos y excluidos.
# set Test args
set 2011-02-24 2011-02-26 "junk"
from="$1"
till="$2"
file="$3"
# EITHER ==== +++++++++
# Ouptut lines between two parameter dates INCLUDING the parameter dates
awk -v from=$from -v till=$till '
($2 >= from) && ($2 <= till) { print $0 ; next }
($2 > till) { exit }' "$file"
# OR ======== ---------
# Ouptut lines between two parameter dates EXCLUDING the parameter dates
awk -v from=$from -v till=$till '
($2 > from) && ($2 < till) { print $0 ; next }
($2 >= till) { exit }' "$file"
Prueba una fecha (ordenada) en el campo 2 ... Aquí hay un ejemplo de los datos de prueba
98 2011-02-05 xxxx
99 2011-02-05 xxxx
100 2011-02-06 xxxx
101 2011-02-06 xxxx
Y aquí está el generador de datos de prueba .
awk -v from="$from" -v till="$till" '($2 >= from) { if ($2 <= till) { print } else { exit }' "$file"
if
declaración adicional en total (ni siquiera 1 por línea), es decir. el flujo lógico es efectivamente el mismo, y la diferencia en el tiempo de ejecución se contaría en nanosegundos ... La única razón por la que no usé "else" es que este es efectivamente mi primer awk
script (aparte de un día 4 años Hace cuando jugué con algunos ejemplos) ... y ese es el primer mecanismo de bifurcación funcional que encontré ... (y como se mencionó. Es igual de rápido). Generalmente uso sed
Tryq
Si en su archivo de registro tiene las fechas en este formato YYYY-MM-DD
, entonces, para encontrar todas las entradas para decir, 2011-02-10, puede hacer:
grep 2011-02-10 log_file
Ahora, digamos, si desea encontrar las entradas para 2011-02-10 y 2011-02-11, entonces, nuevamente use grep
pero con múltiples patrones:
grep -E '2011-02-10|2011-02-11' log_file
grep
buscará todo el archivo, incluso si el intervalo de fechas se encuentra al comienzo del archivo. En promedio, esto duplica el tiempo de una búsqueda, en comparación con "exit-after-last-item-in-range" ... Solo me molesto en mencionar esto debido al tamaño de archivo de 8 GB mencionado en la pregunta, Su Los resultados del tiempo grep son casi idénticos al ejemplo sed aquí (1min 58sec). Aquí está el enlace a los resultados de mis pruebas de tiempo: paste.ubuntu.com/573477
Trabajar con este tamaño de archivos siempre es difícil.
Un camino a seguir podría ser dividir este archivo en un par de pequeños, para hacer esto puede usar el comando dividir.
split -d -l 50000 ToBigFile.data file_
Incluso si está dividido, aún puede trabajar con el archivo como si fuera uno que usa un bash for loop
for f in `ls file_*`; do cat $f; done;
Pero en lugar del gato puede usar grep invertido para deshacerse de los datos no deseados, eso es irrelevante para esto. (o el tipo de refinamiento que necesita).
En este punto, solo trabajará con muchos archivos más pequeños, y los comandos que los otros mencionados anteriormente funcionarán de manera más suave en muchos archivos más pequeños.
Y cuando haya terminado, puede usar un segundo bucle for para construir nuevamente el nuevo archivo más pequeño.
for f in `ls file_*`; do cat $f >> NewFile.data ; done;
Actualización Dado que comenzamos a dividir los datos en varios archivos, va a haber mucho trabajo con el disco duro y eso lleva tiempo. (En esta pregunta aparentemente 5min).
Por otro lado, los próximos pasos probablemente serían más rápidos.
Por lo tanto, este método probablemente no tiene sentido para la operación simple grep, awk, sed, pero si los patrones de búsqueda se vuelven más complicados, podría volverse más rápido.
perl -wlne '/^2011-02-24/ .. /^2011-02-25/ and print' log_file