extract average time from ping -c
Asked Answered
A

8

22

I want to extract from the command ping -c 4 www.stackoverflow.com | tail -1| awk '{print $4}' the average time.

107.921/108.929/110.394/0.905 ms

Output should be: 108.929

Arrant answered 9/3, 2012 at 13:35 Comment(0)
N
51

One way is to just add a cut to what you have there.

ping -c 4 www.stackoverflow.com | tail -1| awk '{print $4}' | cut -d '/' -f 2
Nonaligned answered 9/3, 2012 at 13:40 Comment(2)
thx, that did the trick. Although I am wondering about a better way with less pipes and eventually with better performance.Arrant
@jack: after a minimum of four seconds for getting the actual data the small overhead in this pipeline probably won't ever matter.Baronet
C
13

ping -c 4 www.stackoverflow.com | tail -1| awk -F '/' '{print $5}' would work fine.

"-F" option is used to specify the field separator.

Chalk answered 9/3, 2012 at 13:42 Comment(2)
I wonder, is it possible to also get packet loss if it's non-zero?Aestheticism
You can remove tail: ping -c 4 www.stackoverflow.com | awk -F '/' 'END {print $5}'Shamrock
L
5

This might work for you:

ping -c 4 www.stackoverflow.com | sed '$!d;s|.*/\([0-9.]*\)/.*|\1|'
Langlauf answered 9/3, 2012 at 14:24 Comment(0)
B
4

Promoting luissquall's very elegent comment to an answer:

 ping -c 4 www.stackoverflow.com | awk -F '/' 'END {print $5}'
Bolton answered 9/3, 2012 at 13:35 Comment(0)
K
4

The following solution uses Bash only (requires Bash 3):

[[ $(ping -q -c 4 www.example.com) =~ \ =\ [^/]*/([0-9]+\.[0-9]+).*ms ]] \
&& echo ${BASH_REMATCH[1]}

For the regular expression it's easier to read (and handle) if it is stored in a variable:

regex='= [^/]*/([0-9]+\.[0-9]+).*ms'
[[ $(ping -q -c 4 www.example.com) =~ $regex ]] && echo ${BASH_REMATCH[1]}
Kellykellyann answered 16/3, 2012 at 11:51 Comment(1)
You might want to change the regex to '= [^/]*/([0-9.]+).*ms' to include average values without any decimal places.Elseelset
E
3

Direct extract mean time from ping command:

ping -w 4 -q www.duckduckgo.com  | cut -d "/" -s -f5

Options:

-w time out 4 seconds
-q quite mode
-d delimiter 
-s skip line without delimiter
-f No. of field - depends on your system - sometimes 5th, sometimes 4th

I personly use is this way:

if [ $(ping -w 2 -q www.duckduckgo.com | cut -d "/" -s -f4 | cut -d "." -f1) -lt 20 ]; then
 echo "good response time"
else 
 echo "bad response time"
fi
Exude answered 24/7, 2016 at 2:5 Comment(0)
P
0

Use these to get current ping as a single number:

123.456: ping -w1 -c1 8.8.8.8 | tail -1| cut -d '=' -f 2 | cut -d '/' -f 2

123: ping -w1 -c1 8.8.8.8 | tail -1| cut -d '=' -f 2 | cut -d '/' -f 2 | cut -d '.' -f 1

Note that this displays the average of only 1 ping (-c1), you can increase the sample size by increasing this number (i.e. -c1337)

This avoids using awk (like @Buggabill posted), which doesn't play nice in bash aliases + takes a nanosecond longer

Ponzo answered 24/12, 2019 at 10:11 Comment(1)
Better to use functions instead of aliases anyhow; then you don't need to convert your code into a prependable string at all, can inject arguments at any point in the code desired, and can reuse those functions inside scripts (where aliases are disabled by default).Androsphinx
M
-1

None of these worked well for me due to various issues such as when a timeout occurs. I only wanted to see bad ping times or timeouts and wanted PING to continue quickly, and none of these solutions worked. Here's my BASH script that works well to do both. Note that in the ping command, response time is limited to 1 second.

I realize this does not directly answer the OP's question, however it does provide a good way to deal with some issues that occur with some of the incomplete "solutions" provided here, thus going beyond the scope of the OPs question, which others coming here are looking for (I cite myself as an example), so I decided to share for those people, not specifically OP's question.

while true
do
###Set your IP amd max milliseconds###
  ip="192.168.1.53"
  maxms=50
###do not edit below###
  err="100% packet loss"
  out="$(ping -c 1 -i 1 -w 1 $ip)"
  t="$(echo $out | awk -F '/' 'END {print $5}')"
  t=${t%.*}
  re='^[0-9]+$'

  if ! [[ $t =~ $re ]] ; then
    if [[ $out == *"$err"* ]] ; then
      echo "`date` | ${ip}: TIMEOUT"
    else 
      echo "error: Not a number: ${t} was found in: ${out}"
    fi
  else
    if [ "$t" -gt $maxms ]; then
      echo "`date` | ${ip}: ${t} ms"
    fi
  fi
done
Meave answered 2/3, 2021 at 0:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.