Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I would like to get the number from rating as output from this

# nc localhost 9571 
language:
language:en_ZA.UTF-8
language:en_ZW.UTF-8
session-with-name:Ubuntu Classic (No effects):gnome-session --session=2d-gnome
session-with-name:Ubuntu (Safe Mode):gnome-session -f --session=2d-gnome
session-with-name:Ubuntu Classic:gnome-session --session=classic-gnome
xsession:/etc/X11/Xsession
rating:94

I can do it like this

# nc localhost 9571 | grep rating | cut -d: -f2
94

but could awk be used instead for a simpler solution?

share|improve this question
    
This question appears to be off-topic because it is about programming in the Awk interface and is more relevant on StackOverflow.com –  Magellan Oct 11 '13 at 19:43
add comment

7 Answers

up vote 32 down vote accepted
$ nc localhost 9571 | awk -F: '/rating/ { print $2 }'
share|improve this answer
7  
Can give wrong results if any of the field values or names contain the string "rating", i.e. one of the session names has the word "rating" in it. Better: awk -F: '$1 == "rating" {print $2}' –  Ingmar Hupp Oct 4 '11 at 0:39
3  
Or maybe awk -F: '/^rating:/ { print $2 }'? –  Michael Kjörling Oct 4 '11 at 12:45
    
I know that, but I convert based on the OP's command. –  quanta Oct 4 '11 at 12:47
add comment

You can also use sed,

nc localhost 9571 | sed -n "s/^rating:\([\d]*\)/\1/p"

This will make sure that "rating" starts the line, and that digits follow the rating:

share|improve this answer
add comment

While quanta's answer is the easiest and the one I would write too, I bet you didn't know GNU awk (gawk) can do networking too? You can write the entire thing with awk if you really want:

BEGIN {
    FS = ":"
    f = "/inet/tcp/0/127.0.0.1/9571"
    while ((f |& getline) > 0)
        if ($1 ~ /^rating$/) {print $2}
}

This might be useful if a server doesn't have nc installed, nc has restricted perms, or if you just really like awk.

share|improve this answer
    
Oooh. Nice. Networking and a coprocessing example. –  Dr. Edward Morbius Jun 29 '12 at 0:04
add comment

yes, you can (and should) use (one) awk instead of (two) grep and cut:

$ nc localhost 9571 | awk -F: '/^rating:/ { print $2 }'

Be sure to match you line as good as you can to avoid ugly bugs.

  • /rating/ works,
  • /^rating/ is better (safer),
  • /^rating:/ is best (in this case).
share|improve this answer
add comment

You can also just use the shell:

nc localhost 9571 | 
while IFS=: read key val; do [[ $key = "rating" ]] && echo "$val"; done
share|improve this answer
    
This is the quickest way - and prevents spawning any processes beyond nc. Nice! –  David Oct 3 '11 at 15:50
add comment

Quanta beat me to it, but I'll include a sed variant if you're that way inclined:

nc localhost 9571 | sed -ne 's/^rating://p'

Ditto what MadHatter said, though. Your current solution is perfectly sound. (Although I'd grep for "^rating:" rather than just the word to ensure you only get the line you want.)

share|improve this answer
    
I love sed! It is so underutilized and underappreciated... –  David Oct 3 '11 at 15:59
add comment

It can:

nc localhost 9571  | awk -F: '{ if ($1 == "rating") print $2 }' 

(I don't know what you're doing with localhost above, so used your output as input to my awk command, then replaced the "cat" with "nc ..." - but it should be fine.)

But why would you do this? The UNIX way is to have lots of small tools, each of which does one thing well, strung together via pipelines, rather than using larger multifunction tools. You need to select a single matching line, the select one field therefrom: grep selects lines with matches, and cut selects fields from input lines; they're perfect for the task. But if you really do want to do it all-in-one with awk, well, there you go.

share|improve this answer
    
One reason is that using grep and cut requires spawning two processes, and using awk (or sed) requires only one. Spawning a process is computationally expensive. Also, unlike using perl or ruby (et al), sed and awk are much more lightweight up front. –  David Oct 3 '11 at 15:48
2  
Fair enough, though I note that the size of the awk binary on my (F15) system is 360948 bytes, while the grep and cut binaries together are 170824. So less cycles with only one fork+exec, but more memory, and more IO to get the binary off disc. Honestly, I doubt that any of these considerations matter on modern systems, but if you're minded to minimise, there you go! –  MadHatter Oct 3 '11 at 16:46
    
Foo Bah: thanks for your edit proposal, but quanta made a later post than mine which is even more streamlined than your suggestion. I preferred mine because it's easier for an entry-level awk user to see how it works, and therefore rejected your edit. Thank you for the thought, though! –  MadHatter Oct 3 '11 at 16:50
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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