在字符串/时间键之间提取并重新格式化文本

时间:2018-12-31 10:31:04

标签: linux bash logging

我在提取两个字符串之间的文本时遇到问题。

我有这样的日志文件(示例数据):

2018-12-31 09:49:24 addData [data=data]</br>
2018-12-31 09:49:25 publishData .......................
2018-12-31 09:49:26 createDoc [xml=
<mail>
    <recipent>doctor who</recipent>
</mail>]
<attempt>1</attempt>]
2018-12-31 09:49:26 createDoc [xml=
<clientHash>hash</clientHash>
<content>context</content>]
2018-12-31 09:51:27 exampleService [count=1]

我的代码: perl -ne 'print if (/09:40/ .. /09:50/)' server.log | sed -n '/createDoc/,/]/p'

我的输出是:

2018-12-31 09:49:26 createDoc [xml=<mail><recipent>doctor who</recipent>
</mail>]
<attempt>1</attempt>]
2018-12-31 09:49:26 createDoc [xml=
<clientHash>hash</clientHash>
<content>context</content>]

但是我只想要这样的xml:

<element>
<mail><recipent>doctor who</recipent>
</mail>
<attempt>1</attempt>
</element>
<element>
<mail><recipent>doctor who</recipent>
</mail>
<clientHash>hash</clientHash>
<content>context</content>
</element>

2 个答案:

答案 0 :(得分:0)

我会为此使用Awk。如果您有GNU Awk,甚至可以轻松解析时间戳。

awk -v start=$(date -d "09:40" +%s) \
    -v end=$(date -d "09:50" +%s) '           
    /^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} / {
        if ($0 ~ / createDoc \[xml=/) {
            split($1, ymd, /-/)
            split($2, hms, /:/)
            when = mktime(ymd[1] " " ymd[2] " " ymd[3] " " hms[1] " " hms[2] " " hms[3])
            p = (when >= start && when <= end)
            if (p) $0 = substr($0, 36)
        }
        else p = 0
    }
    p { sub(/\]$/, ""); print }' file.log

这在某种程度上以Linux为中心-除了GNU Awk(用于mktime函数)之外,date语法还特定于GNU date。 (在OSX上,尝试date -j %H:%M:%S 09:40:00 +%s。)

答案 1 :(得分:0)

假设我们有 tmp.log ,如下所示。

ApiController

我们可以结合一些基本命令以获得所需的输出。

  • 从整个日志文件中提取包含行的xml。
  • 根据'['字符分割字符串并获取第二个元素。

2018-12-31 09:49:24 addData [data=data]</br> 2018-12-31 09:49:25 publishData ....................... 2018-12-31 09:49:26 createDoc [xml=<mail><recipent>doctor who</recipent></mail>]<attempt>1</attempt>] 2018-12-31 09:49:26 createDoc [xml=<clientHash>hash</clientHash><content>context</content>] 2018-12-31 09:51:27 exampleService [count=1]

这将产生类似的内容:

cat tmp.log | grep xml | awk  'BEGIN { FS = "[" } ; { print $2 }'

如果您也想摆脱最后一个字符'] 。还要再添加一个awk。

xml=<mail><recipent>doctor who</recipent></mail><attempt>1</attempt>]
xml=<clientHash>hash</clientHash><content>context</content>]

我知道这不是最酷的方法,至少它易于理解和工作。