Slowly muddling my way through learning how to manipulate variables for a bash script I'm writing. I'm trying to use AWK (tried Grep but not granular enough I don't think) to pull the source and dest from iftop.

The base iftop command I'm using is:

sudo iftop -t -L1 -s1 -f "dst host 10.0.0"

I can switch the dst to src to get the reverse. So the sample output from the command above is:

interface: eth0
IP address is:
MAC address is: b8:27:eb:6a:26:84
Listening on eth0
   # Host name (port/service if enabled)            last 2s   last 10s  last 40s cumulative
   1                               =>         0b         0b         0b         0B                                <=     1.14Kb     1.14Kb     1.14Kb       291B
Total send rate:                                       480b       480b       480b
Total receive rate:                                  1.29Kb     1.29Kb     1.29Kb
Total send and receive rate:                         1.76Kb     1.76Kb     1.76Kb
Peak rate (sent/received/total):                       480b     1.29Kb     1.76Kb
Cumulative (sent/received/total):                      120B       331B       451B

I'm trying to use AWK to output the two IP addresses (or could be domains) to variables I can then do something with in bash.

If I use a command such as:

 sudo iftop -t -L1 -s1 -f "dst host 10.0.0" 2> /dev/null | awk '/^   1 / {print $2}'

That gives me the first IP or domain, but I now need the 2nd line down. I tried using something like:

 sudo iftop -t -L1 -s1 -f "dst host 10.0.0" 2> /dev/null | awk '/^   1 /{c=2} c&&c-- {print $2}'

This almost works, but because of the white spacing on the 2nd line, AWK counts what is column 2 in the first line as column 1 in the second, so the output I get is:

I feel like I'm close but I can't work out how to use a single AWK command to spit out the right two numbers.

I can't easily run a second pattern compare for the 2nd number as the white space before the IP or domain isn't enough to go on I don't think, so ideally I want to match on the first, then move to the next line but choose column 1 rather than column 2.

I also want to avoid running a second iftop command as the results may be different to the first.

I then need to know how to convert those to variables for a bash script rather than print them to screen.

Any ideas?



 ... | awk '$1 == "1" {print $2 ; l=NR+1 ; } NR == l { print $1 ;}'


  • $1 == "1" select line where first field is 1
  • {print $2 print it's value
  • l=NR+1 ; } remember next line
  • NR == l select second line
  • { print $1 ;} print first field

remember awk doesn't think in term of column, just field.

thoses two lines are equivalent using $1 $2

 hello world
       hello              world

Assigning to var

... | awk '$1 == "1" {printf "A=%s\n",$2 ; l=NR+1 ; } NR == l { printf "B=%s\n",$1 ;}' > /tmp/.var
. /tmp/.var

last line is a dot (.) a space () and /tmp/.var

  • printf in awk need a comma after argument.
  • This works perfectly thank you - how would I go about assigning the two outputs to seperate variables? – Matthew Hodder Mar 6 '18 at 12:35
  • Thanks for the var assignment, if I run the above command I get the following error: awk: run time error: not enough arguments passed to printf("A=%s13.107.4.50")? - I think I'm doing something wrong with that last line? – Matthew Hodder Mar 7 '18 at 9:26
  • I ended up writing this to an array which did the job, I'll mark this as the answer though and edit my final solution in the main comment – Matthew Hodder Mar 7 '18 at 9:53
  • - printf in awk need a comma after argument. (i fixed in my answer) – Archemar Mar 7 '18 at 9:54

You could use this:

sudo iftop -t -L1 -s1 -f "dst host 10.0.0" | grep -E '=>|<=' | cut -c 5- | awk '{ print $1 }'

which returns:

The problem is that the number of "columns" is not the same on the following two lines. In the command above cut is used to delete the first 5 characters, thus it deletes the "1".

 1                         =>         0b         0b         0b         0B                          <=     1.14Kb     1.14Kb     1.14Kb       291B

With grep:

... | grep -oP '^\s+\d* \K(\d+\.){3}\d+'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.