【问题标题】:how can i improve my sed command to extract data form ping log file?如何改进我的 sed 命令以从 ping 日志文件中提取数据?
【发布时间】:2022-01-09 06:09:57
【问题描述】:

按照细节,该网站要求我包含一些文本,因为主要是代码,所以我输入了这句话,但我认为它是不言自明的

示例日志文件:

jue 08 abr 2021 13:33:49 -03 : VA  John Doe  : PING google.com (17x.2xx.1x2.4x): 56 data bytes

--- google.com ping statistics ---
100 packets transmitted, 100 packets received, 0% packet loss
round-trip min/avg/max = 40.462/50.166/62.318 ms
jue 08 abr 2021 13:35:35 -03 : VA  John Doe  : PING google.com (17x.2xx.1x2.4x): 56 data bytes

--- google.com ping statistics ---
100 packets transmitted, 99 packets received, 1% packet loss
round-trip min/avg/max = 42.055/48.856/136.962 ms
jue 08 abr 2021 13:37:21 -03 : VA  John Doe  : PING google.com (17x.2xx.1x2.4x): 56 data bytes

--- google.com ping statistics ---
100 packets transmitted, 100 packets received, 0% packet loss
round-trip min/avg/max = 40.058/47.762/64.169 ms

到目前为止我的命令:

cat sample.log | sed -r -e '/^... [0-9]+ ... [0-9]{4} [0-9]{2}:[0-9]{2}/{s/(... [0-9]+ ... [0-9]{4} [0-9]{2}:[0-9]{2}).*$/\1/g;n;d}' -e '/^--- google.*$/d' -e 's/100 packets transmitted.*([0-9]+%) packet.*$/\1/' -e '/round-trip/d'

得到的结果:

jue 08 abr 2021 13:33
0%
jue 08 abr 2021 13:35
1%
jue 08 abr 2021 13:37
0%

理想的结果:

jue 08 abr 2021 13:33, 0%
jue 08 abr 2021 13:35, 1%
jue 08 abr 2021 13:37, 0%

【问题讨论】:

    标签: bash sed


    【解决方案1】:

    假设:

    • 丢包率总是出现在以NUM% packet loss结尾的行中。
    • 日期和时间始终位于以data bytes 结尾的行中。

    然后,使用 GNU sed(在您显示的两个完整记录上进行测试):

    $ sed -nE '/packet loss$/{s/.*\s([0-9]+%) packet loss$/\1/;h}
      /data bytes$/{s/(.{24}).*/\1/;G;s/\n/, /;p}' sample.log
    jue 08 abr 2021 13:35:35, 0%
    jue 08 abr 2021 13:37:21, 1%
    

    【讨论】:

    • 谢谢,我喜欢它的外观。阅读 man 以了解 h 和 G 命令的作用以及模式空间和保持空间是什么...
    • this answer 非常清楚模式和保持空间。现在我想知道表达式中的新行是否可以替换为其他字符 @renaud-pacalet ?
    • 在 sed 脚本中,我建议将换行符替换为 , (逗号空格)。如果它不是您想要的,请用其他任何东西替换它。
    • 我指的是第二个“地址”(或任何 sed 调用它)之前的换行符,即“/data bytes$/”。我诱导它与第一个分开,并意识到用分号替换它是一样的。我需要它在一行中才能轻松复制/粘贴。
    • 哦!对不起,我误解了你的问题。是的,sed 命令可以用换行符或分号分隔。
    【解决方案2】:

    第一个解决方案:这应该是awk 的任务。使用您显示的示例,请尝试关注awk 代码。

    awk -v OFS=", " '
    match($0,/^[a-zA-Z]+ [0-9]{2} [a-zA-Z]+ [0-9]{4} ([0-9]{2}:){2}[0-9]{2}/){
      val=substr($0,RSTART,RLENGTH-3)
      next
    }
    /packets transmitted/{
      print val,$(NF-2)
      val=""
    }
    '  Input_file
    

    解释: 简单的解释是,如果找到匹配的然后通过正则表达式创建具有匹配值(捕获值)的 val 变量。使用 next 将跳过此处的所有进一步声明。然后检查条件是否包含packets transmitted 然后打印 val 以及该行的倒数第三个字段。然后取消 val 变量。

    正则表达式的解释:

    ^[a-zA-Z]+               ##Matching small/capital letters 1 or more occurrences from starting.
     [0-9]{2}                ##Matching space followed by 2 occurrences of digits.
     [a-zA-Z]+               ##Matching space followed by 2 occurrences of small/capital letters.
     [0-9]{4}                ##Matching space followed by followed by 4 digits.
     ([0-9]{2}:){2}[0-9]{2}  ##Matching space followed by digits 2 occurrences followed by colon and this whole group should occur 2 times followed by 2 occurrences of digits.
    


    第二个解决方案: 在这里使用 GNU awk 我们可以在 RS 变量中使用几乎相同的正则表达式,并且可以获得如下所需的结果:

    awk -v RS='[a-zA-Z]+ [0-9]{2} [a-zA-Z]+ [0-9]{4} [0-9]{2}:[0-9]{2}|[0-9]{1,3}%' -v OFS=", " '
    RT{
      val=(val?val (++count%2==0?ORS:OFS):"") RT
    }
    END{
      print val
    }
    '  Input_file
    

    【讨论】:

    • 感谢您的回答,我对 awk 不熟悉,但我只是尝试了一下并没有得到我想要的结果...混合了 x% 行和其他带有日期时间的行除了 x% 以空格分隔...
    • @mrossw,通过您展示的示例,我的两个答案/解决方案对我来说都很好。您的实际 Input_file 是否与所示示例相同?
    • @mrossw,还要确保您的文件中没有回车符,如果您在其中看到控制 M 字符,请尝试运行命令 cat -v your_file 一次,然后您需要在运行我的代码之前删除它们.
    【解决方案3】:

    要获得所需的格式,您可以将输出通过管道传输到:

    sed 'N;s/\n/, /'
    

    最后的命令变成了(注意你不需要 cat 到 sed,因为它接受文件名作为参数):

    sed -r -e '/^... [0-9]+ ... [0-9]{4} [0-9]{2}:[0-9]{2}/{s/(... [0-9]+ ... [0-9]{4} [0-9]{2}:[0-9]{2}).*$/\1/g;n;d}' -e '/^--- google.*$/d' -e 's/100 packets transmitted.*([0-9]+%) packet.*$/\1/' -e '/round-trip/d'  sample.log | sed 'N;s/\n/, /'
    
    

    输出

    jue 08 abr 2021 13:33, 0%
    jue 08 abr 2021 13:35, 1%
    jue 08 abr 2021 13:37, 0%
    
    

    【讨论】:

    • 谢谢,这得到了我需要的东西。我希望对表达式进行一些优化。
    猜你喜欢
    • 1970-01-01
    • 2014-09-28
    • 1970-01-01
    • 2022-10-13
    • 1970-01-01
    • 2023-03-23
    • 2018-10-28
    • 2023-03-14
    • 1970-01-01
    相关资源
    最近更新 更多