处理Ping数据(正则表达式)

时间:2014-03-02 20:29:31

标签: regex sed

我正在尝试创建一个脚本来处理来自ping的数据。所以它将来自标准格式的文件,带有时间戳:

PING google.com (4.34.16.45) 56(84) bytes of data.
[1393790120.617504] 64 bytes from 4.34.16.45: icmp_req=1 ttl=63 time=25.7 ms
[1393790135.669873] 64 bytes from 4.34.16.45: icmp_req=2 ttl=63 time=30.2 ms
[1393790150.707266] 64 bytes from 4.34.16.45: icmp_req=3 ttl=63 time=20.6 ms
[1393790161.195257] 64 bytes from 4.34.16.45: icmp_req=4 ttl=63 time=35.2 ms

--- google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 45145ms
rtt min/avg/max/mdev = 20.665/27.970/35.246/5.390 ms

我想将其剪切为时间戳,时间和请求编号(请注意,这是来自不同的数据集,作为示例):

0.026202538597014928 26.2 1
0.53210253859701473 24.5 2
1.0482067203067074 32.0 3
1.6627447926949444 139.6 4
2.2686229201578056 237.1 5

我意识到我需要使用sed来实现这一目标。但我仍然对于正确切割数据的表达方式感到困惑。我想我会有这样的东西:

cat $inFile | grep -o "$begin$regex$end" | sed "s/$end//g" | sed "s/$begin//g" > $outFile

我只是不确定$ begin和$ end会是什么。

TL; DR帮我理解正则表达式?

3 个答案:

答案 0 :(得分:2)

您可以尝试以下命令:

sed -ne '
    2,/^$/ { 
        /^$/! { 
            s/^\[\([^]]*\).*icmp_req=\([0-9]*\).*time=\([0-9.]*\).*$/\1 \3 \2/
            p 
        } 
    }
' infile

它使用-n开关来避免输入行的自动打印。它选择第二个和第一个空白之间的一系列行,并且对于每一行我都要对要提取的文本进行分组。

假设infile包含问题的内容,它会产生:

1393790120.617504 25.7 1
1393790135.669873 30.2 2
1393790150.707266 20.6 3
1393790161.195257 35.2 4

使用更简单的Scrutinizer's解决方案

更新(请参阅评论):

sed -n 's/^\[\([^]]*\).*icmp_req=\([0-9]*\).*time=\([0-9.]*\).*$/\1 \3 \2/p' infile

答案 1 :(得分:2)

为了更好的衡量,这是一个awk解决方案:

awk -F "[][ =]"  '/^\[/ { print $2, $13, $9 }' file
  • 利用awk基于正则表达式作为分隔符将行解析为字段的功能 - 此处,以下任何字符:[] 或{{ 1}}。
  • 对于以=开头的行,只需按索引打印出感兴趣的字段。

答案 2 :(得分:0)

对于纯正则表达式解决方案,请参阅以下表达式:

\[([\d\.]*)].*?=(\d+).*?=([\d\.]*) ms

您可以在此处查看在线演示:

Regex101.com