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.
source to share
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
- Linux:
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 }'
source to share
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
.
source to share