2016-04-19 11 views
1

Ich möchte mehrere Protokolldateien innerhalb eines bestimmten Datumsbereichs zusammenführen. Zum Beispiel habe ich 5 Tage von Log-Dateien in einem Verzeichnis:Shell-Skript: Dateien innerhalb eines Datumsbereichs zusammenführen

server.log.2016-04-14-00 
server.log.2016-04-14-01 
. . . 
server.log.2016-04-18-23 
server.log.2016-04-19-00 
server.log.2016-04-19-01 

Ich weiß, ich Katze, die Dateien verschmelzen kann, aber wie kann ich Code in einem Shell-Skript, so dass nur die Dateien zum Beispiel zwischen , 2016-04-17-22 und 2016-04-18-01 ausgewählt?

+1

Bitte lernen Sie, die Suchfunktion ** zu benutzen, bevor Sie Fragen stellen tion. Die Suche nach '[bash] log filter filter' gibt 6 Einträge zurück, während '[bash] log file' über 4000 zurückgibt. Bitte schauen Sie ;-) ... Viel Glück. – shellter

+0

@ChrisC Ist das Datumsformat yyyy-mm-dd-hh? –

+0

Ja, das ist das Datumsformat, das im Protokolldateinamen verwendet wird. –

Antwort

1

Das folgende Skript akzeptiert die Protokolldatei des Servers als erstes Argument. Zwei wichtige Variablen sind from_date und to_date welche die von-zu Bereich steuern. Sie sind im Skript fest codiert, und Sie sollten dies möglicherweise ändern, um die Flexibilität des Skripts zu erhöhen.

#!/bin/bash 

# Server's log file. 
server_log_file=$1 
# The date from which the relevant part of the log file should be printed. 
from_date='2016/04/14 00:00' 
# The date until which the relevant part of the log file should be printed. 
to_date='2016/04/19 01:00' 

# Uses 'date' to convert a date to seconds since epoch. 
# Arguments: $1 - A date acceptable by the 'date' command. e.g. 2016/04/14 23:00 
date_to_epoch_sec() { 
    local d=$1 
    printf '%s' "$(date --date="$d" '+%s')" 
} 

# Convert 'from' and 'to' dates to seconds since epoch. 
from_date_sec=$(date_to_epoch_sec "$from_date") 
to_date_sec=$(date_to_epoch_sec "$to_date") 

# Iterate over log file entries. 
while IFS=. read -r s l date; do 
    # Read and parse the date part. 
    IFS=- read -r y m d h <<< "$date" 
    # Convert the date part to seconds since epoch. 
    date_sec=$(date_to_epoch_sec "$y/$m/$d $h:00") 

    # If current date is within range, print the enire line as it was originally read. 
    if ((date_sec > from_date_sec && date_sec < to_date_sec)); then 
     printf '%s.%s.%s\n' "$s" "$l" "$date" 
    fi 

done < "$server_log_file" 

Um es zu testen ich die folgende Datei erstellt, mit dem Namen Logfile:

server.log.2016-04-14-00 
server.log.2016-04-14-01 
server.log.2016-04-18-23 
server.log.2016-04-19-00 
server.log.2016-04-19-01 

Anwendungsbeispiel (Skriptname ist sof):

$ # Should print logs from 2016/04/14 00:00 to 2016/04/19 01:00 
$ ./sof logfile 
server.log.2016-04-14-01 
server.log.2016-04-18-23 
server.log.2016-04-19-00 
Verwandte Themen