Как разделить каждую строку файла журнала на столбцы SQL?(возможно, используя регулярное выражение для разбиения) - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть файл журнала, который я должен включить в QlikSense.QlikSense читает строку в строку файла журнала, поэтому мне нужно выражение для разбиения этой строки на нужные столбцы.

Файл журнала выглядит так (его размер составляет около 2,5 миллионов записей):

202.32.92.47 - - [01/Jun/1995:00:00:59 -0600] "GET /~scottp/publish.html" 200 271 - -
ix-or7-27.ix.netcom.com RFC-1413 - [01/Jun/1995:00:02:51 -0600] "GET /~ladd/ostriches.html" 200 205908 - "Mozilla/5.0 (X11; U; Linux i686; es-ES;rv:1.7.5)" 
ppp-4.pbmo.net - John Thomas [07/Dec/1995:13:20:28 -0600] "GET /dcs/courses/cai/html/introduction_lesson/index.html HTTP/1.0" 500 - "http://www.wikipedia.org/" "Mozilla/5.0 (X11; U; Linux i686; es-ES;rv:1.7.5)" 
ppp-4.pbmo.net - John Thomas [07/Dec/1995:13:20:37 -0600] "GET /dcs/courses/cai/html/index.html HTTP/1.0" 500 4528 - - 
lbm2.niddk.nih.gov RFC-1413 John Thomas [07/Dec/1995:13:21:03 -0600] "GET /~ladd/vet_libraries.html" 200 11337 "http://www.wikipedia.org/" - 

Структура каждой строки этого файла журнала: IP ID NAME DATETIME TIMEZONE METHOD DIR STATUS MB WEB FROM.Итак, я разделю предыдущий пример журнала, используя || для лучшей визуализации:

|| ix-or7-27.ix.netcom.com || RFC-1413 || - || [01/Jun/1995:00:02:51 || -0600] "GET || /~ladd/ostriches.html" || 200 || 205908 || - || "Mozilla/5.0 (X11; U; Linux i686; es-ES;rv:1.7.5)" ||
|| ppp-4.pbmo.net || - || John Thomas || [07/Dec/1995:13:20:28 || -0600] || "GET || /dcs/courses/cai/html/introduction_lesson/index.html HTTP/1.0" || 500 || - || "http://www.wikipedia.org/" || "Mozilla/5.0 (X11; U; Linux i686; es-ES;rv:1.7.5)" ||
|| ppp-4.pbmo.net || - || John Thomas || [07/Dec/1995:13:20:37 || -0600] || "GET || /dcs/courses/cai/html/index.html HTTP/1.0" || 500 || 4528 || - || - ||
|| lbm2.niddk.nih.gov || RFC-1413 || John Thomas || [07/Dec/1995:13:21:03 || -0600] || "GET || /~ladd/vet_libraries.html" || 200 || 11337 || "http://www.wikipedia.org/" || - ||

Так, например, для первой строки:

IP = ix-or7-27.ix.netcom.com 
ID = RFC-1413 
NAME = - 
DATETIME = 01/Jun/1995 00:02:51 
TIMEZONE = -0600 
METHOD = GET 
DIR: /~ladd/ostriches.html
STATUS = 200 
MB = 205908 
WEB = -
FROM = Mozilla/5.0 (X11; U; Linux i686; es-ES;rv:1.7.5)

Итак, значение каждого поляможет быть text или -.Я пробовал много способов включить его, но я не добился этого.

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

Я подумал, что, возможно, использование RegEx (шаблон) может решить мою проблему, но у меня естьЯ не знаю, как это сделать.

РЕДАКТИРОВАТЬ 1:

Если решение моей проблемы - это шаблон регулярных выражений, то нужно сделать следующее:

  • Первый параметр: перехватить все до пробела
  • Второй параметр: перехватывать все в пространство
  • Третий параметр: перехватывать все до [
  • Четвертый параметр: перехватывать все до пробела
  • Пятый параметр:поймать все до]
  • Шестой параметр: поймать все в пространство
  • Седьмой параметр: поймать все в пространство
  • Восьмой параметр: поймать все до пространства
  • Девятый параметр: поймать все в пространство
  • Десятый параметр: поймать все внутри "" или -
  • Одиннадцатый параметр: поймать все внутри "" или -

Есть идеи, как я мог получить это?

Спасибо.

Ответы [ 3 ]

0 голосов
/ 13 декабря 2018

Вдохновленный этим SO-ответом , вы можете попробовать следующее регулярное выражение и затем очистить его, удалив конечные " и [] символы.

(.*?)\s(?=(?:[^"]*"[^"]*")*[^"]*\Z)

Если вы хотите регулярное выражениеЕдинственное решение, вы можете попробовать подключиться к нему, чтобы удалить эти последние символы.Я бы предложил использовать https://regex101.com/

PS. Группа 1 этого регулярного выражения содержит все нужные вам фрагменты данных.

0 голосов
/ 15 января 2019

Просто используйте функцию SubField , https://help.qlik.com/en-US/sense/November2018/Subsystems/Hub/Content/Sense_Hub/Scripting/StringFunctions/SubField.htm

пример:

LOAD

text

, подполе (текст,'||', 1) как 1_параметр

, подполе (текст, '||', 2) как 2_параметр

и т. Д. *

0 голосов
/ 13 декабря 2018

Мне когда-то приходилось анализировать несколько файлов журнала 36 ГБ с различной длиной (после разделения на пространство).Попробовал RegExp и все заработало, но тут все по другому.Возможно, вам просто нужно сделать line.split(" ").length, затем проверить счетчик, а затем выполнить свою логику, основываясь на этом.

    PrintWriter out=new PrintWriter("/directory/log.txt"),errorsOut=new PrintWriter("/directory/log-errors.txt");
    for(String line:lines){
      try{
        if(line.split(" ").length==11){
            String result=line[0]+"|"+line[1]+"|"+line[2]+"|"+line[3]replace("[", "").replaceFirst(":", " ")+"|"+...(etc)...
            out.println(line);
      }catch(Exception e) {
          errorsOut.println(line);
      }
        } else if(line.split(" ").length==14) { ... }
    }

Возможно, не самый эффективный, но для 2,5 МБ он не умрет, он поймаетмного, и если есть ошибки, вы можете записать их в отдельный файл для последующей проверки.

Я также пробовал logstash и другие средства просмотра журналов Enterprise.Некоторые из них хороши, но большинство не предлагают универсального решения.

...