2

I have a script that prints out the average time when pinging a server, shown below:

ping -c3 "${I}" | tail -1 | awk '{print $4}' | cut -d '/' -f 2 | sed 's/$/\tms/'

How can I add the line number to output of the script above when pinging a list of servers ??

my actual output when pinging list of 3 host is:

6.924 ms
100.099 ms
7.756 ms

I want the output to be like this:

1,6.924 ms
2,100.099 ms
3,7,756 ms

so that this can be read by excel :) Thank in advanced!!

4
  • Are those commands in a loop? Commented Nov 18, 2013 at 16:46
  • exactly :) In a for loop :) Commented Nov 18, 2013 at 16:50
  • I'm confused by your output. The sed in your example looks like it is putting a tab before the "ms". Do you want a tab or a space? Commented Nov 19, 2013 at 14:20
  • I just want a space there :) but actually a tab is good also :) Commented Nov 19, 2013 at 16:33

3 Answers 3

3

The standard tool for line numbering is nl. Pipe your output to nl -s, That is:

for I; do
  ping -c3 "${I}" | awk -F/ 'END{print $5, "\tms"}' 
done | nl -s,

Since you haven't specified how the list is generated, I'm just showing the case where the list of hosts to be pinged is given on the command line. Note that this introduces leading whitespace before the line number, so you might want to filter that through sed to remove.

Of course, this script is spending most of its time waiting for the ping, and you probably want to speed it up by running the pings in parallel. In that case, it is better to add the line number at the beginning so you can get a stable sort in the output:

line=1
{ for I; do ping -c3 $I | awk -F/ 'END{
     printf( "%d,%s\tms\n", line,$5 )}' line=$line &
     : $((line +=1 ))
done; wait; } | sort -n

In this case, the wait is not necessary since sort will block until all of the pings have closed their output, but the wait becomes necessary if you add any processes in the pipeline before the sort that do not necessarily wait for all of their input before doing any processing, so it is a good practice to leave the wait in place.

Sign up to request clarification or add additional context in comments.

Comments

2

Pipe your output through perl:

echo -e 'aa\nbb' | perl -ne 'print $., ",", $_'

Output:

1,aa
2,bb

4 Comments

+1 or awk: | awk '{print NR "," $0}'. You could also write perl -pe 's/^/$.,/'
OP is looping through a command and its output is only a single line for each iteration. Hence, I think this approach is not valid for this case.
@jkshah answered before the comment clarifications. He could still pipe his entire script output through perl, but agree that it is not optimal in this case.
Just pipe the loop into perl/awk: for host in $list; do ...; done | perl -pe 's/^/$.,/'
2

Is that what you want?

C=1
for I in 'host1' 'host2' 'host3'
do
  ping -c3 "${I}" | tail -1 | awk '{print $4}' | cut -d '/' -f 2 | echo "$C,$(sed 's/$/\tms/')"
  C=$((C+1))
done

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.