extraer datos del archivo de registro en el rango de tiempo especificado

Quiero extraer información de un archivo de registro usando un script de shell (bash) basado en el rango de tiempo. Una línea en el archivo de registro se ve así:

172.16.0.3 - - [31/Mar/2002:19:30:41 +0200] "GET / HTTP/1.1" 200 123 "" "Mozilla/5.0 (compatible; Konqueror/2.2.2-2; Linux)" 

Quiero extraer intervalos específicos de datos. Por ejemplo, necesito ver solo los eventos que ocurrieron durante los últimos X minutos o X días a partir de los últimos datos grabados. Soy nuevo en scripts de shell pero he intentado usar el comando grep.

Puedes usar sed para esto. Por ejemplo:

 $ sed -n '/Feb 23 13:55/,/Feb 23 14:00/p' /var/log/mail.log Feb 23 13:55:01 messagerie postfix/smtpd[20964]: connect from localhost[127.0.0.1] Feb 23 13:55:01 messagerie postfix/smtpd[20964]: lost connection after CONNECT from localhost[127.0.0.1] Feb 23 13:55:01 messagerie postfix/smtpd[20964]: disconnect from localhost[127.0.0.1] Feb 23 13:55:01 messagerie pop3d: Connection, ip=[::ffff:127.0.0.1] ... 

Cómo funciona

El -n le dice a sed que no muestre cada línea del archivo que lee (comportamiento predeterminado).

La última p después de las expresiones regulares le indica que imprima líneas que coincidan con la expresión anterior.

La expresión '/pattern1/,/pattern2/' imprimirá todo lo que esté entre el primer patrón y el segundo patrón. En este caso, imprimirá cada línea que encuentre entre la cadena Feb 23 13:55 y la cadena Feb 23 14:00 .

Más información aquí .

Use grep y expresiones regulares, por ejemplo, si desea un intervalo de registros de 4 minutos:

 grep "31/Mar/2002:19:3[1-5]" logfile 

devolverá todas las líneas de registro entre las 19:31 y las 19:35 del 31 / marzo / 2002. Suponiendo que necesita los últimos 5 días a partir del 27 de septiembre de 2011, puede usar lo siguiente:

 grep "2[3-7]/Sep/2011" logfile 

Bueno, he pasado un tiempo en tu formato de fecha …..

sin embargo, finalmente lo resolví …

tomemos un archivo de ejemplo (llamado logFile ), lo hice un poco corto. por ejemplo, desea obtener los últimos 5 minutos de registro en este archivo:

 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET ### lines below are what you want (5 mins till the last record) 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:30:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:30:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:30:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:30:41 +0200] "GET 

aquí está la solución:

 # this variable you could customize, important is convert to seconds. # eg 5days=$((5*24*3600)) x=$((5*60)) #here we take 5 mins as example # this line get the timestamp in seconds of last line of your logfile last=$(tail -n1 logFile|awk -F'[][]' '{ gsub(/\//," ",$2); sub(/:/," ",$2); "date +%s -d \""$2"\""|getline d; print d;}' ) #this awk will give you lines you needs: awk -F'[][]' -v last=$last -vx=$x '{ gsub(/\//," ",$2); sub(/:/," ",$2); "date +%s -d \""$2"\""|getline d; if (last-d<=x)print $0 }' logFile 

salida:

 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:30:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:30:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:30:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:30:41 +0200 "GET 

EDITAR

Puede observar que en la salida, el [y] desaparecen. Si los quiere de regreso, puede cambiar la última línea de awk print $0 -> print $1 "[" $2 "]" $3

Utilicé este comando para encontrar los últimos registros de 5 minutos para el evento particular ” DHCPACK “, intente a continuación:

 $ grep "DHCPACK" /var/log/messages | grep "$(date +%h\ %d) [$(date --date='5 min ago' %H)-$(date +%H)]:*:*" 

Puede usar esto para obtener los tiempos actuales y de registro:

 #!/bin/bash log="log_file_name" while read line do current_hours=`date | awk 'BEGIN{FS="[ :]+"}; {print $4}'` current_minutes=`date | awk 'BEGIN{FS="[ :]+"}; {print $5}'` current_seconds=`date | awk 'BEGIN{FS="[ :]+"}; {print $6}'` log_file_hours=`echo $line | awk 'BEGIN{FS="[ [/:]+"}; {print $7}'` log_file_minutes=`echo $line | awk 'BEGIN{FS="[ [/:]+"}; {print $8}'` log_file_seconds=`echo $line | awk 'BEGIN{FS="[ [/:]+"}; {print $9}'` done < $log 

Y compare las log_file_* y current_* .