【问题标题】:Filtering multiple specific values from line of Log in Linux从 Linux 中的 Log 行过滤多个特定值
【发布时间】:2019-07-05 10:52:10
【问题描述】:

我有这些类型的日志:

"09/Feb/2019:11:25:51 +0000" client=10.0.0.148 method=GET request="GET /flask2 HTTP/1.1" [...] request_time=0.011 [...] upstream_header_time=0.010

我已经设法从日志中提取奇异值(例如,只有请求时间),如下所示:

cat <logfile> | sed -n -e 's/^.*request_time=//p' | sed -n -e 's/ .*$//p'

我想过滤这些值,以便收到以下信息:

"09/Feb/2019:11:25:51 +0000" "GET /flask2 HTTP/1.1" 0.011

这个存在:

<time> <request> <request-time>

这样的事情要怎么完成?

【问题讨论】:

  • 试试sed 's/^\("[^"]*"\).*request=\("[^"]*"\).*=\([0-9.]*\)$/\1 \2 \3/',见demo

标签: regex linux logging awk sed


【解决方案1】:

grep

$ grep -oP '^"[^"]+"|request(|_time)=\K("[^"]+"|\S+)' file | paste -s

"09/Feb/2019:11:25:51 +0000"    "GET /flask2 HTTP/1.1"  0.011

根据输出,您得到的是request,而不是method

【讨论】:

    【解决方案2】:

    考虑将 GNU awk 用于 FPAT:

    $ cat tst.awk
    BEGIN {
        FPAT="([^[:space:]=]+=)?(\"[^\"]+\"|[^[:space:]]+)"
    }
    {
        for (i=1; i<=NF; i++) {
            print i, "<" $i ">"
        }
    }
    
    $ awk -f tst.awk file
    1 <"09/Feb/2019:11:25:51 +0000">
    2 <client=10.0.0.148>
    3 <method=GET>
    4 <request="GET /flask2 HTTP/1.1">
    5 <[...]>
    6 <request_time=0.011>
    7 <[...]>
    8 <upstream_header_time=0.011>
    

    鉴于上述解析输入的方法,您可以轻松识别要输出的字段,甚至可以简单地通过名称或位置引用它们,例如:

    $ cat tst.awk
    BEGIN {
        FPAT="([^[:space:]=]+=)?(\"[^\"]+\"|[^[:space:]]+)"
    }
    {
        f["time"] = $1
        for (i=2; i<=NF; i++) {
            tag = val = $i
            sub(/=.*/,"",tag)
            sub(/^[^=]+=/,"",val)
            f[tag] = val
        }
    
        print f["time"], f["request"], f["request_time"]
    }
    
    $ awk -f tst.awk file
    "09/Feb/2019:11:25:51 +0000" "GET /flask2 HTTP/1.1" 0.011
    

    考虑一下,如果您想在 CSV 中以特定的字段顺序额外打印客户端 IP 地址和方法,并且所有字段都被双引号括起来,或者做任何其他事情,例如:

    $ cat tst.awk
    BEGIN {
        FPAT="([^[:space:]=]+=)?(\"[^\"]+\"|[^[:space:]]+)"
        OFS=","
    }
    {
        f["time"] = $1
        for (i=2; i<=NF; i++) {
            tag = val = $i
            sub(/=.*/,"",tag)
            sub(/^[^=]+=/,"",val)
            gsub(/^"|"$/,"",val)
            f[tag] = "\"" val "\""
        }
    
        print f["time"], f["request"], f["request_time"], f["client"], f["method"]
    }
    
    $ awk -f tst.awk file
    "09/Feb/2019:11:25:51 +0000","GET /flask2 HTTP/1.1","0.011","10.0.0.148","GET"
    

    【讨论】:

      【解决方案3】:

      试试这个 Perl 单行代码

      perl -ne ' /(^.+?").+?request=(.+?").+?request_time=(\S+)/ and print "$1 $2 $3" '
      

      使用给定的输入

      $ cat  req.logs
      "09/Feb/2019:11:25:51 +0000" client=10.0.0.148 method=GET request="GET /flask2 HTTP/1.1" [...] request_time=0.011 [...] upstream_header_time=0.010
      
      
      $ perl -ne ' /(^.+?").+?request=(.+?").+?request_time=(\S+)/ and print "$1 $2 $3" ' req.logs
      "09/Feb/2019:11:25:51 +0000" "GET /flask2 HTTP/1.1" 0.011
      $
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-06-14
        • 2023-03-29
        • 1970-01-01
        • 2021-08-07
        • 2018-12-08
        • 1970-01-01
        • 2022-11-02
        • 1970-01-01
        相关资源
        最近更新 更多