
Meine Protokolldatei sieht wie folgt aus:
10.434.22.334 - unauthenticated 10/Aug/2020:23:45:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 10/Aug/2020:23:45:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 11/Aug/2020:23:34:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 12/Aug/2020:23:45:43 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 13/Aug/2020:23:43:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 14/Aug/2020:23:33:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
Ich möchte die obigen Einträge durchsuchen, indem ich einen Datumsbereich angebe, wie unten:
./Logsearch.sh 10/Aug/2020 13/Aug/2020
Erwartetes Ergebnis:
10.434.22.334 - unauthenticated 10/Aug/2020:23:45:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 10/Aug/2020:23:45:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 11/Aug/2020:23:34:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 12/Aug/2020:23:45:43 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 13/Aug/2020:23:43:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
Wie kann ich das machen?
Irgendeine Idee, wie ich ein Skript für meine Abfrage schreiben kann? Mein Betriebssystem ist Solaris 11. Bitte stellen Sie ein Beispielskript zur Verfügung.
Antwort1
Das sieht wie ein Standard-HTTP-Zugriffsprotokoll aus. Warum also nicht verwenden, grep
um ein Muster der gewünschten Daten abzugleichen?
$ grep '1[0-3]/Aug/2020' access_log
10.434.22.334 - unauthenticated 10/Aug/2020:23:45:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 10/Aug/2020:23:45:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 11/Aug/2020:23:34:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 12/Aug/2020:23:45:43 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 13/Aug/2020:23:43:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
Das Grep-Muster „1[0-3]/Aug/2020“ verwendet den Bereichsausdruck [0-3]. Dieser Ausdruck entspricht einem einzelnen Zeichen, das die Werte 0,1,2,3 annehmen kann. Kombinieren Sie dies mit dem Rest des Ausdrucks, und Sie erhalten 10/Aug/2020, 11/Aug/2020, 12/Aug/2020 und 13/Aug/2020 als mögliche Muster. grep
druckt die Zeilen aus dem Protokoll aus, die diesen Mustern entsprechen.
Antwort2
Sie können ein spezielles Tool zur Strukturierung von Text wie Miller verwenden (https://github.com/johnkerl/miller) und Renn
mlr --nidx then filter 'strftime(strptime($4,"%d/%b/%Y:%H:%M:%S"),"%Y-%m-%d") >="2020-08-11" && strftime(strptime($4,"%d/%b/%Y:%H:%M:%S"),"%Y-%m-%d") <="2020-08-13"' input.txt
haben
10.434.22.334 - unauthenticated 11/Aug/2020:23:34:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 12/Aug/2020:23:45:43 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 13/Aug/2020:23:43:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
Ich habe einen Filter angewendet, um alles zwischen 2020-08-11
und zu haben2020-08-13
Einige Notizen:
--nidx
, um das Eingabe- und Ausgabeformat festzulegen (https://bit.ly/3h3UvN3)filter
Filter anwenden;strftime(strptime($4,"%d/%b/%Y:%H:%M:%S"),"%Y-%m-%d") >="2020-08-11"
ist einer der Filter. Mitstrptime
stelle ich das Eingabedatumsformat (%d/%b/%Y:%H:%M:%S
) des vierten Feldes ($4
) ein. Mitstrftime
ändere ich das Datumsformat in%Y-%m-%d
Antwort3
Verwenden vonRaku(früher bekannt als Perl_6)
~$ raku -e 'my $start_date = DateTime.new("2020-08-11").in-timezone(28800); \
my $stop_date = DateTime.new("2020-08-13").in-timezone(28800); \
my @a = lines.map: *.words; my @b = do for @a { \
.[0..2], \
.[3..4].join.subst(/^ (\d**2) \/ (Aug) \/ (\d**4) \: /, {"$2-08-$0T"} ) \
.subst(/ (\+\d**2) (\d**2) $/, {"$0:$1"} ).DateTime, \
.[5..*] }; \
.put if .[1] ~~ $start_date .. $stop_date for @b;' file
#ODER:
~$ raku -e 'my $start_date = DateTime.new("2020-08-11").in-timezone(28800); \
my $stop_date = DateTime.new("2020-08-13").in-timezone(28800); \
my @a = lines.map(*.words).map({ \
.[0..2], ( \
.[3].subst(/^ (\d**2) \/ (Aug) \/ (\d**4) \: /, {"$2-08-$0T"} ), \
.[4].subst(/ (\+\d**2) (\d**2) $ /, {"$0:$1"} )).join.DateTime, \
.[5..*] }); \
.put if .[1] ~~ $start_date .. $stop_date for @a;' file
Oben sind die Antworten in Raku geschrieben, einem Mitglied der Perl-Familie von Programmiersprachen. Raku hat ISO 8601
integrierte DateTime-Objekte.
Kurz gesagt, das Datum/die Uhrzeit in jeder Zeile wird in ein DateTime-Objekt umgewandelt ISO 8601
. Wenn jedes der lines
in durch Leerzeichen getrennte aufgeteilt wird words
, befinden sich die Datums-/Uhrzeitelemente in nullindizierten Spalten .[3]
und . Diese werden mit itute-Befehlen und ed .[4]
umgewandelt, um DateTime-Objekte zu erstellen . Dann wird jede Zeile geprüft, um zu sehen, ob das DateTime-Objekt in einem gewünschten Bereich liegt .subst
join
ISO 8601
$start .. $stop
Beispieleingabe:
10.434.22.334 - unauthenticated 10/Aug/2020:23:45:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 10/Aug/2020:23:45:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 11/Aug/2020:23:34:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 12/Aug/2020:23:45:43 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 13/Aug/2020:23:43:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 14/Aug/2020:23:33:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
Beispielausgabe (beide Codebeispiele):
10.434.22.334 - unauthenticated 2020-08-11T23:34:45+08:00 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 2020-08-12T23:45:43+08:00 "GET /eai/random.jsp HTTP/1.1" 200 74
https://www.iso.org/iso-8601-date-and-time-format.html
https://docs.raku.org
https://raku.org