代码之家  ›  专栏  ›  技术社区  ›  JuMoGar

如何将日志文件的每一行分割成SQL列?(可能使用regex进行拆分)

  •  0
  • JuMoGar  · 技术社区  · 6 年前

    我有一个日志文件,我必须将它包含在qliksense中。qliksense逐行读取日志文件,因此我需要一个expresion来将这一行拆分为所需的列。

    日志文件如下(其大小约为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:

    如果我的问题的解决方案是regex模式,则应执行以下操作:

    • 第一个参数:catch all up to space
    • 第二个参数:赶上太空
    • 第三个参数:catch all up to[
    • 第四个参数:赶上太空
    • 第五个参数:catch all up to]
    • 第六个参数:赶上太空
    • 第七个参数:赶上太空
    • eigth参数:catch all up to space
    • 第九个参数:追赶太空
    • 第十个参数:catch all inside“”或-
    • 第十一个参数:catch all inside“”或-

    知道我怎么得到它吗?

    谢谢您。

    3 回复  |  直到 6 年前
        1
  •  0
  •   esca2791    6 年前

    我曾经不得不解析多个不同长度的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和其他企业日志查看器。有些是好的,但大多数并没有提供一个“全面”的解决方案。

        2
  •  0
  •   LIvanov    6 年前

    受到启发 this SO answer 您可以尝试以下正则表达式,然后通过删除尾部来对其进行消毒。 " [] 字符。

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

    如果您想只使用ReGEX解决方案,可以尝试插入其中,以便删除那些尾随字符。我建议你用 https://regex101.com/

    这个regex的p.s.group 1包含您想要的所有数据片段。

        3
  •  0
  •   Chernov    6 年前

    只使用 子场 函数, https://help.qlik.com/en-US/sense/November2018/Subsystems/Hub/Content/Sense_Hub/Scripting/StringFunctions/SubField.htm

    例子:

    负载

    文本

    ,子字段(文本,“”,1)作为1_参数

    ,子字段(文本,“”,2)作为2_参数

    等。。。