САС для анализа журналов Apache между отметкой времени - PullRequest
0 голосов
/ 25 апреля 2018

Я пытаюсь проанализировать журнал и получить строки между отметкой времени. Опробованный подход sed, как показано ниже, но сталкивается с проблемой с регулярным выражением

Шаблон журнала:

IP - - [20/Apr/2018:14:25:37 +0000] "GET / HTTP/1.1" 301 3936 "-" "
IP - - [20/Apr/2018:14:44:08 +0000]
----------------------------------

IP- - [20/Apr/2018:20:43:46 +0000]

Мне нужно получитьстроки между 14:25 и 20:43 для 20 апреля, поскольку журнал содержит и другие даты.

Пробовал это:

sed -n '/\[14:25/,/\[20:43/p' *-https_access.log.1

, но не работает.

Ответы [ 4 ]

0 голосов
/ 25 апреля 2018

Лучшее решение - использовать awk для этого. Что вам нужно сделать, это конвертировать ваши метки времени в Unix-время, а затем сделать сравнение. В awk вы можете сделать это, используя mktime()

mktime(datespec [, utc-flag ]): Превратить даты в метку времени в той же форме, что и systime(). Это похоже на функция с тем же именем в ISO C. Аргумент, datepec, является строка вида YYYY MM DD HH MM SS [DST]. Строка состоит из шесть или семь чисел, представляющих, соответственно, полный год в том числе век, месяц с 1 по 12, день месяца с 1 до 31, часы дня от 0 до 23, минуты от 0 до 59, секунда от 0 до 60,55 и дополнительный флаг перехода на летнее время.

Чтобы преобразовать формат времени формы 20/Apr/2018:14:25:37 +0000 в 2018 04 20 14 25 37 +0000

awk -v tstart="20/Apr/2018:14:25:00" -v tend = "20/Apr/2018:20:43:00" \
     'function tounix(str) {
        split(str,a,"/|:| ")
        return mktime(a[3]" "month[a[2]]" "a[1]" "a[4]" "a[5]" "a[6])
     }
     BEGIN{
       month["Jan"]="01";month["Feb"]="02";month["Mar"]="03"
       month["Apr"]="04";month["May"]="05";month["Jun"]="06"
       month["Jul"]="07";month["Aug"]="08";month["Sep"]="09"
       month["Oct"]="10";month["Nov"]="11";month["Dec"]="12"
       FS="\\[|\\]"
       t1=tounix(tstart)
       t2=tounix(tend)
     }
     { t=tounix($2) }
     (t1<=t && t<=t)' <file>

Этот метод является надежным, поскольку он будет выполнять сравнение реального времени, которое не зависит от високосных годов, переходов между днями / месяцами / годами ... В отличие от других предоставленных решений, этот метод также не требует наличия дата tstart и tend в file

0 голосов
/ 25 апреля 2018

Чтобы напечатать строки между match1 и match2 с помощью sed или awk, вы можете сделать:

sed -n '/match1/,/match2/p' inputfile
awk '/match1/,/match2/' inputfile

в вашем примере match1 равно 20/Apr/2018:14:25 и match2 равно 20/Apr/2018:20:43.Поэтому любая из этих команд должна работать для вас:

sed -n '/20\/Apr\/2018:14:25/,/20\/Apr\/2018:20:43/p' inputfile
awk '/20\/Apr\/2018:14:25/,/20\/Apr\/2018:20:43/' inputfile

или использовать | в качестве разделителя sed для предотвращения слеша:

sed -n '\|20/Apr/2018:14:25|,\|20/Apr/2018:20:43|p' inputfile
0 голосов
/ 25 апреля 2018

sed не подходит, потому что трудно сравнивать элемент (например, день и час).

с awk (самокомментируется):

awk -F '[ []' '
  {
  # separt date and hour then rebuild the fields
  sub(/:/, " ", $5);$0=$0""
  }

  # print if it s the day and between the 2 hour (string compare works in this case)
  $5 ~ /20.Apr.2018/ && $6 >= "04:25" &&  $7 < "20:44"
  ' YourFile

больше, мы можем использовать переменную дляукажите дату и время в качестве параметра для awk (здесь нет цели)

0 голосов
/ 25 апреля 2018

Так как вы упомянули, что хотите журналы на 20 апреля, я бы предложил что-то вроде:

$ sed -n '/20\/Apr\/2018:14:25/,/20\/Apr\/2018:20:43/p' *-https_access.log.1

Вероятность конфликта с ложными совпадениями очень мала, если в другом месте встречается "20:43".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...