21

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

creativeDev
  • 1,113
  • 2
  • 13
  • 20

8 Answers8

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
Buggabill
  • 13,726
  • 4
  • 42
  • 47
  • thx, that did the trick. Although I am wondering about a better way with less pipes and eventually with better performance. – creativeDev Mar 09 '12 at 13:48
  • 7
    @jack: after a minimum of four seconds for getting the actual data the small overhead in this pipeline probably won't ever matter. – Eduardo Ivanec Mar 09 '12 at 14:41
12

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

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

raj
  • 3,769
  • 4
  • 25
  • 43
5

This might work for you:

ping -c 4 www.stackoverflow.com | sed '$!d;s|.*/\([0-9.]*\)/.*|\1|'
potong
  • 55,640
  • 6
  • 51
  • 83
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]}
xebeche
  • 905
  • 7
  • 20
  • 1
    You might want to change the regex to '= [^/]*/([0-9.]+).*ms' to include average values without any decimal places. – gsbabil Mar 16 '12 at 12:32
3

Promoting luissquall's very elegent comment to an answer:

 ping -c 4 www.stackoverflow.com | awk -F '/' 'END {print $5}'
Community
  • 1
  • 1
msanford
  • 11,803
  • 11
  • 66
  • 93
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
xerostomus
  • 466
  • 4
  • 11
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

allanlaal
  • 227
  • 3
  • 9
  • 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). – Charles Duffy Mar 08 '20 at 16:52
-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
Vitalik
  • 2,724
  • 4
  • 32
  • 43
KyferEz
  • 377
  • 1
  • 3
  • 13