如何将日志文件的每一行拆分为sql列(可能使用正则表达式进行拆分)

mqkwyuun  于 2021-06-17  发布在  Mysql
关注(0)|答案(3)|浏览(243)

我有一个日志文件,我必须包括到qliksense它。qliksense逐行读取日志文件,因此我需要一个表达式来将这一行拆分为所需的列。
日志文件如下所示(其大小约为250万个条目):

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:

如果我的问题的解决方案是正则表达式模式,那么接下来应该做:
第一个参数:追赶到太空
第二个参数:追赶空间
第三个参数:赶上[
第四个参数:追赶太空
第五个参数:赶上]
第六个参数:追赶太空
第七个参数:追赶太空
eigth参数:追赶空间
第九个参数:追赶太空
第十个参数:catch all inside“”或-
第十一个参数:catch all inside“”或-
你知道我怎么得到它吗?
谢谢您。

jtjikinw

jtjikinw1#

我曾经不得不解析多个长度不同的36gb日志文件(在空间上拆分之后)。尝试了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.5mb它不会死,它会捕获很多错误,如果有错误,你可以把它们写进一个单独的文件,稍后检查。
我也尝试过logstash和其他企业日志查看器。有些是好的,但大多数没有提供一个“包罗万象”的解决方案。

bfrts1fy

bfrts1fy2#

受这个so答案的启发,您可以尝试下面的正则表达式,然后通过删除尾随来清理它 " 以及 [] 查尔斯。

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

如果您想要只使用regex的解决方案,您可以尝试插入该解决方案,以便删除那些尾随字符。我建议使用https://regex101.com/
p、 这个正则表达式的第1组包含所有你想要的数据。

gg58donl

gg58donl3#

只需使用子字段函数,https://help.qlik.com/en-us/sense/november2018/subsystems/hub/content/sense_hub/scripting/stringfunctions/subfield.htm
例子:
加载
文本
,子字段(文本,“| |”,1)作为1|u参数
,子字段(文本,“| |”,2)作为2|u参数
等。。。

相关问题