
Мой файл журнала выглядит следующим образом:
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
Я хочу выполнить поиск по приведенным выше записям, указав диапазон дат, как показано ниже:
./Logsearch.sh 10/Aug/2020 13/Aug/2020
Ожидаемый результат:
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
Как я могу это сделать?
Есть идеи, как написать скрипт для моего запроса. Возможно, ОС — Solaris 11. Пожалуйста, предоставьте пример скрипта.
решение1
Это похоже на стандартный журнал HTTP-доступа, так почему бы не использовать его grep
для сопоставления шаблона нужных вам дат?
$ 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
Шаблон grep '1[0-3]/Aug/2020' использует выражение диапазона [0-3]. Это выражение соответствует одному символу, который может принимать значения 0,1,2,3. Объедините это с остальной частью выражения, и вы получите 10/Aug/2020, 11/Aug/2020, 12/Aug/2020 и 13/Aug/2020 в качестве возможных шаблонов. grep
выведет строки из журнала, соответствующие этим шаблонам.
решение2
Вы можете использовать специализированный инструмент структурированного текста, такой как Miller (https://github.com/johnkerl/miller) и запустить
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
иметь
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
Я применил фильтр, чтобы отобразить все между 2020-08-11
и2020-08-13
Некоторые примечания:
--nidx
для установки формата ввода и вывода (https://bit.ly/3h3UvN3)filter
применить фильтр;strftime(strptime($4,"%d/%b/%Y:%H:%M:%S"),"%Y-%m-%d") >="2020-08-11"
один из фильтров. Используяstrptime
я устанавливаю формат даты ввода (%d/%b/%Y:%H:%M:%S
) четвертого поля ($4
). Используяstrftime
я изменяю формат даты в%Y-%m-%d
решение3
С использованиемРаку(ранее известный как 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
#ИЛИ:
~$ 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
Выше приведены ответы, написанные на языке Raku, входящем в семейство языков программирования Perl. В Raku ISO 8601
встроены объекты DateTime.
Вкратце, Date/Time в каждой строке преобразуется в ISO 8601
объект DateTime. Когда каждый из lines
разбивается на разделенные пробелами words
, элементы Date/Time находятся в столбцах с нулевым индексом .[3]
и .[4]
. Они преобразуются с помощью subst
команд itute и join
ed для создания ISO 8601
объектов DateTime. Затем каждая строка проверяется, попадает ли объект DateTime в требуемый $start .. $stop
диапазон.
Пример ввода:
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
Пример вывода (оба примера кода):
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