theiwarlock
theiwarlock

Reputation: 89

Processing Ping Data (Regular Expressions)

I'm trying to create a script to process data from ping. So it will come from a file in the standard format with timestamps:

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

I want to cut it to just the timestamp, time and request number like so (note this is from a different data set, given as an example):

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

I realize I need to use sed to accomplish this. But I'm still really confused as to what the expressions would be to cut to the data properly. I imagine I would have something along these lines:

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

I'm just not sure what $begin and $end would be.

TL;DR Help me understand regular expressions?

Upvotes: 2

Views: 150

Answers (3)

mklement0
mklement0

Reputation: 437618

For good measure, here's an awk solution:

awk -F "[][ =]"  '/^\[/ { print $2, $13, $9 }' file
  • Takes advantage of awk's ability to parse lines into fields based on a regex as the separator - here, any of the following chars: [, ],  , or =.
  • Simply prints out the fields of interest by index, for lines that start with [.

Upvotes: 2

Vasili Syrakis
Vasili Syrakis

Reputation: 9601

For a pure regex solution, see this expression:

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

You can view an online demo here:

Regex101.com

Upvotes: 0

Birei
Birei

Reputation: 36262

You can try following command:

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

It uses -n switch to avoid automatic print of input lines. It select a range of lines between the second one and the first one that is blank, and for each one I do grouping of the text I want to extract.

Assuming infile with the content of the question, it yields:

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

UPDATE with simpler Scrutinizer's solution (see comments):

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

Upvotes: 2

Related Questions