Failed to capture bash paste output.

( ping -n apple.com | ack -o --flush '((?<=icmp_seq=)[0-9]+|(?<=time=)[0-9]+[.][0-9]+)' | paste - - ) > ~/Desktop/ping_ouput.txt

      

It doesn't seem to work for some reason, whereas if I pick up

| paste - -

      

it works fine. I need to join every other line along with a tab instead of a new line. Any ideas are appreciated.

+3


source to share


2 answers


Update:

By default, it ping

outputs output indefinitely until it completes
, so your pipe will continue to produce output and grow the output file indefinitely, and your command will never exit on its own .

Thus, you need to limit the number of pings performed ; eg:.

  • using the parameter -c count

    to stop after the specified number of peaks.
  • on BSD-like systems you can use -o

    to stop after the first successful ping.
  • alternatively, you can stop after the specified timeout in seconds, no matter how many packets were received:
    • Linux: -w timeout

    • BSD-like systems: -t timeout

By the way, to redirect a pipeline to a file, you don't need to wrap it in its (...)

entirety, which would uselessly create a (lowercase) subshell.


In doing so, the following was written: (a) the specific symptom was known and (b) before the OP discovered in a comment that their platform was OSX. The commands below show alternatives to the OP extract command; -c 2

was added to limit ping to 2 attempts.

tivn's answer found at least a potential problem in your team: the assumption that values time

always have a decimal point, which is not supported on Linux platforms; on BSD / OSX platforms, however, there are always 3 decimal places.

You can work around this issue and also concatenate sequential lines like this (I use 127.0.0.1

instead apple.com

for easier testing):



Using GNU sed

(Linux) or BSD sed

(BSD-like systems including OSX):

ping -c 2 -n 127.0.0.1 |
  sed -E '1d; s/^.* icmp_seq=([^ ]+).* time=([^ ]+).*$/\1'$'\t''\2/'

      


Alternative solutions using awk

:

ping -c 2 -n 127.0.0.1 | awk -F'[ =]' -v OFS='\t' 'NR>1 { print $6, $10 }'

      


If you'd rather not rely on the field indices, here's an alternative (still relying on the field icmp_seq

to precede time

and in order to precede the space):

ping -c 2 -n 127.0.0.1 | awk -F' (icmp_seq|time)=' -v OFS='\t' '
  NR>1 { sub(" .+$", "", $2); sub(" .+$", "", $3)
  print $2, $3 }'

      


+2


source


You are not providing the sample input you received from ping

, so it is not clear what the problem is. But I think your problem is the result time

of ping

not always contain the point .

, for example 64 bytes from x.x.x.x: icmp_seq=1 ttl=63 time=137 ms

. You can try the following command:

( ping -n yahoo.com \
  | ack -o --flush '((?<=icmp_seq=)\d+|(?<=time=)[\d.]+)' \
  | stdbuf -o0 paste - - \
) > ~/Desktop/ping_ouput.txt

      



Edit: Following a comment from the OP, the problem may come from a buffered command paste

. Try adding stdbuf -o0

to the command paste

.

+1


source







All Articles