Okay, here's a quick example; me isolating a host's IPV4 in three steps:

ip -br a lo UNKNOWN 127.0.0.1/8 ::1/128 eth0 DOWN wlan0 UP 192.168.0.101/24 fe80::9fcd:45fb:1e0f:a1cc/64 
ip -br a | awk '/wlan0/ {print $3}' 192.168.0.101/24
ip -br a | awk '/wlan0/ {print $3}' | awk -F '/' '{print $1}'192.168.0.101

Instead of invoking a second instance of awk (piping the output of one into the next); how can it be done all in one go?


Just wanted to say: The question isn't about parsing the output of ip. I just needed a quick example to help illustrate the question; this was the first thing that I came up with. The real question is summed up in the title.

Anyway, for what it's worth (I'll have to check it, but I'm pretty sure); this is what I've done in the (recent) past:

ip -br a s dev wlan0 | awk -F '[ /]*' '{print $3}'192.168.0.101
share|improve this question

You can use gsub for that like:

ip -br a | awk '/wlan0/ {gsub(/\/.*/, ""); print $3}'
share|improve this answer

Just change the definition of field separator to include both spaces and /:

$ ip -br a | awk -F'[[:blank:]/]+' '/wlan0/{print $3}'192.168.0.101

The option -F'[[:blank:]/]+' tells awk to use any combination of blanks, tabs or slashes as the field separator on input.

share|improve this answer

For this instance, the easiest way to do it is probably set multiple separators using a regex:

ip -br a | awk -F '[\t /]*' '/wlan0/ {print$3}'

This makes the field separator any string of /, spaces, or tabs, and then prints the third field.

To do any arbitrary two commands you would like, you pretty much need to learn the full awk programming language. I would recommend against that- I'm sure you have better things to do with your time.

share|improve this answer

Although the other answers solve the underlying problem, they don't really answer the question, "How do I chain awk print statements?"

For this sort of problem, the answer is, "You don't." You use the rest of the language to manipulate the source until you get the desired result - which is what the other two answers do. You only use print to output the final result.

Once you have specified an initial range pattern such as /wlan0/ (or /^wl/ in my case because my WiFi has a different name), your action, the code inside {}, will only operate on input lines that contain that string.

Once you have that, you can do whatever you need to with that input line.

ip -br a | \awk '/^wl/ {ip1=$3gsub(/\/.*/, "", ip1)print ip1}'

This code takes the desired field, puts it in a variable, edits the content of that variable, and then prints it.

The other answer does this same thing more efficiently, but this illustrates a more general case where other steps can be added. You could even save the result to use later with something found on another input line, etc.

For something that might actually look more like "print chaining", awk has an sprintf() function which can do a formatted print of its input into a variable for further processing.

Or, if you're printing more than one thing on a line, your code can use multiple printf() statements without a newline until the last one to build an output line piece by piece.

share|improve this answer

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.