LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   awk multiple lines of output - print one line (https://www.linuxquestions.org/questions/programming-9/awk-multiple-lines-of-output-print-one-line-4175468637/)

nitrohuffer2001 07-05-2013 06:27 PM

awk multiple lines of output - print one line
 
Hi Folks,

I am running a bi-directional iperf and want just a few fields from the output on a single line.

Here is an example of the output from the iperf:
Code:

------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
------------------------------------------------------------
Client connecting to 19.239.243.30, TCP port 5001
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[  5] local 19.150.255.136 port 37639 connected with 19.239.243.30 port 5001
[  4] local 19.150.255.136 port 5001 connected with 19.239.243.30 port 47560
[ ID] Interval      Transfer    Bandwidth
[  5]  0.0-10.2 sec  9344 KBytes  919 KBytes/sec
[  4]  0.0-12.2 sec  512 KBytes  42.1 KBytes/sec

What I would like the output to look like is:

Code:

host 919 42.1
I have been trying with awk but can't get the output exactly how I want it. Any ideas how I could get the desired output?

Thanks.

Kustom42 07-05-2013 06:40 PM

I'm confused do you just want the Bandwidth number printed to the screen?

If so then a simple grep/cut is easier than an awk in my opinion although it can be done by setting your FS and RS with awk.

syg00 07-05-2013 07:06 PM

Awk has regex and conditional logic (amongst other features) - seems perfect for the job. The OP didn't show the code, but something like this might work
Code:

awk '/\/sec$/ {first? second=$7 : first=$7 ; if (second) {print "host ",first,second ; first=second =""} }' infile

Kustom42 07-05-2013 07:12 PM

syg your solution is the more correct one here, but this could be easily accomplished with a much smaller statement:

Code:

grep -i bytes | awk '{print $7" "$8}'

It really depends how robust you want to make this, if you are just trying to pull out two numbers for yourself to see using grep/awk combo that makes sense. If you want to cron this or program it into a script then syg00's awk is the more correct method.


Its always right to use the best tool for the job. Why type out all of the extra junk if its for a one time use? And why would you not want to use a simple grep/awk pipe for a programmatic task that will be repeated often?

Answer: It is much simpler if you have a static set of input that you know exactly what it is and need to one off something quickly while you are sitting at the CLI. However, a simple grep/awk pipe is not reliable if your input changes.

Xeratul 07-06-2013 03:09 AM

part of code under C.
Code:

  fp  = fopen( filetoopen  , "rb" ) ;
  while(!feof(fp))    {
    fgets( lineread  , PATH_MAX , fp );
  printf( "%s" , string_awk_cut( line , delimiter[0] , numberawking) );
  printf("\n");
  }


David the H. 07-07-2013 04:24 AM

I think we need to clarify a few more things here.

1) Is the output static, or are you filtering a continuing stream?
2) What exactly is "host"? It doesn't appear in the input text as shown, so where does it come from? Should it only print once, or is it a stand-in for something that changes in (or depending on) the input?
3) Similarly, do you want all output to appear on a single line, or are there separate lines for different entries, or what?


Making the assumption that "host" is a fixed value, and that you want all "KBytes" values to appear after it, I'd probably use something like this:

Code:

iperf .... | awk 'BEGIN{ printf "%s","host" } /KBytes/ { printf "%s"," "$7 }'
Note the hard space I tacked to the front of the $7, to separate each entry.

You might also want to add an END section to tack a final newline onto the end.

nitrohuffer2001 07-08-2013 04:06 PM

Hi Everyone,

Thanks for all of the helpful advice!

The content is static, it is the output from a bi-directional iperf.

"Host" will be the ip of the system that just ran the iperf. I have an array of IP's that run through a loop and write the output to a file. So the file will look something like:
Code:

10.10.10.5 919 42.1
So ideally the file once the script finishes will look like the above but with more entires and different values on separate lines:

Code:

10.10.10.5 919 42.1 
10.10.10.4 899 49.1
10.10.10.3 789 69.1 
10.10.10.2 999 12.1
etc


Thanks again for all the help!

nitrohuffer2001 07-08-2013 05:26 PM

So,

Adding the END section works great if I run it directly from the shell but when I dump it into the bash script as such:

Code:

/usr/local/bin/iperf -c $i -d -f KBytes | awk 'BEGIN{ printf "%s","'${i}'"" } /KBytes/ { printf "%s"," "$7}  END{ print "" }' >> $file
I get this error:

Code:

awk: BEGIN{ printf "%s","19.239.211.30"" } /KBytes/ { printf "%s"," "$7}  END{ print "" }
awk:                                                                                  ^ unterminated string
^CWaiting for server threads to complete. Interrupt again to force quit.

Yet it works from the shell outside of the bash script.

Thanks.

konsolebox 07-08-2013 08:09 PM

Quote:

Originally Posted by nitrohuffer2001 (Post 4986562)
I get this error:

Code:

awk: BEGIN{ printf "%s","19.239.211.30"" } /KBytes/ { printf "%s"," "$7}  END{ print "" }
awk:                                                                                  ^ unterminated string
^CWaiting for server threads to complete. Interrupt again to force quit.


This is the problem I believe
Code:

"$7
---- Add ----

Also, the extra quote seems wrong:
Code:

"19.239.211.30""

nitrohuffer2001 07-09-2013 12:32 PM

Thanks,

Here is the final win:


Code:

/usr/local/bin/iperf -c $i -d -f KBytes | awk 'BEGIN{ printf "%s","'${i}'" } /KBytes/ { printf "%s"," "$7 }  END{ print "" }' >> $file
Here is a sample of the output file:
Code:

19.239.243.30 932 19.4
19.239.219.30 1528 1158
19.239.227.30 472 722

Thanks for the help.


All times are GMT -5. The time now is 06:46 AM.