0

I am trying to use awk to search the output of a script for a specific line. Can someone explain why this doesnt return the output: 16.72?

my bash script:

speed=$(./speedtest-cli)
awk '/Download:/ {print $2}' $speed

speedtest-cli

pi@raspberrypi ~/Desktop/PiControl $ ./speedtest-cli
Retrieving speedtest.net configuration...
Retrieving speedtest.net server list...
Testing from Charter Communications (xxxxxx)...
Selecting best server based on latency...
Hosted by Charter Communications (yyyy, zz) [67.01 km]: 44.035 ms
Testing download speed........................................
Download: 16.72 Mbit/s
Testing upload speed..................................................
Upload: 3.45 Mbit/s

Note (included in the comments below) I am trying to avoid one-liners because I plan to print multiple lines from the output.

EDIT:

To clarify my end goal. I am trying to run ./speedtest-cli (I am trying not to change this file). I am trying to take its output (the download speed, the upload speed, and the latency) and pass them as individual parameters to another script that will write them to a database. (This project is purely for personal use.... im not trying to use it in an enterprise environment)

From the speedtest-cli output above I want to do this:

MY GOAL:

./another_script 16.72 3.45 44.035 
9
  • This will only work in a script. Commented Feb 28, 2016 at 23:34
  • Sorry, I edited my post to make it clearer that I was running this from a bash script Commented Feb 28, 2016 at 23:35
  • 3
    For a one-liner try: speedtest-cli | awk '{/Download:/} print $2' Commented Feb 28, 2016 at 23:36
  • 1
    have your awk script retrieve multiple-values, no problem. Else save output to a tmp file, then process that. When you use $speed (un-dbl-quoted) the shell turns the data into one big set of words, without new-lines separating the lines. You would see that if you used set -vx to debug/trace your shell script. Good luck. Commented Feb 29, 2016 at 0:51
  • 2
    Please explain your END GOAL. What are you planning to do with the values you extract? The optimal method for gathering an parsing these data will likely depend on what you plan to do with them. (What I'm suggesting here is that this is an XY Problem, and that we can help you achieve your goal better if we know what it is, rather than helping you accelerate into a wall.) Commented Feb 29, 2016 at 2:55

3 Answers 3

3

Your requirements are very vague (big picture - you're telling us HOW you want to do something but not WHAT you want to do) but MAYBE this is what you want:

./speedtest-cli | awk -F': *' '/Download|Hosted by Charter Communications/{print $2}'
44.035 ms
16.72 Mbit/s
Sign up to request clarification or add additional context in comments.

4 Comments

I clarified my end goal in my post, I hope this helps.
When I ran your code above it returned only the Download value (not both) just as an FYI for others who may have been confused about what result to expect by my poorly formatted question.
The regexp above is extremely simple and infallible. If you do awk '/a|b/' file and it only outputs the match for a then b WAS NOT PRESENT in the input file.
Just checked that again after writing it to a file, your regex was correct.
2

First, in answer to your question:

speed=$(./speedtest-cli)
awk '/Download:/ {print $2}' <<< "$speed"

Second, this is almost certainly not what you really need. You could, for example, construct the call you want within bash, and then either use awk's system function, or perhaps echo the entire call.

Another approach would be to assign the values of interest to a bash array, along the lines of:

 a=( $(./speedtest-cli | awk -F ....) )

Comments

1

You've stated that this is your bash script:

#!/bin/bash

speed=$(./speedtest-cli)
awk '/Download:/ {print $2}' $speed

This fails because you are not giving anything to awk to parse. You're setting a variable to contain output from a command, but then treating that variable as if it were a filename.

Awk's command line format looks like this, roughly:

awk [options] awkscript [file ...]

Is $speed a file? No, it is not.

Based on the edit to your question, it looks as if what you're trying to do is simply strip out the numbers that are output from the speedtest-cli command. If the script that can take those numbers can be edited, and does not need options in the order you've specified, the quickest solution is probably something like this:

/path/to/speedtest-cli | egrep -o '[0-9]+\.[0-9]+' | xargs /path/to/anotherscript

This takes the output of speedtest-cli, strips out everything that is not a decimal number, then makes those numbers the options to anotherscript. For the sample input you provided, this is equivalent to running

anotherscript 67.01 44.035 16.72 3.45

2 Comments

I like this solution, but it includes the ip address xxxxx because of the format (12.34.56.12) as the first two parameters
As long as it's consistent, you can account for that in anotherscript, and use only the positional parameters you're interested in.

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.