awk Help

Hi All,

This should be simple, but for some reason I cant figure out why the following wont work:

 ifconfig eth0 |awk 'BEGIN {FS=":"; print "IP Address is: "} $1 == "inet addr" { print $2 }' 

That should print the IP address of eth0. Here is the output of the ifconfig eth0 command:

eth0      Link encap:Ethernet  HWaddr AC:16:2D:75:46:C8  
          inet addr:123.123.123.123  Bcast:123.123.123.255  Mask:255.255.255.0
          inet6 addr: blaa
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:292643058 errors:0 dropped:6400 overruns:0 frame:0
          TX packets:704382748 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:164659504340 (153.3 GiB)  TX bytes:959885251512 (893.9 GiB)
          Interrupt:32 

Im setting the FS=":" and printing the second filed {$2}, so not sure why its not working.

Thanks!
Joe

--- Post updated at 01:40 PM ---

This seems to work, however:

 ip a show eth0 |awk '$1 == "inet" {print $2}' 

Perhaps the issue is the field separator not working correctly?

In the line:

          inet addr:123.123.123.123  Bcast:123.123.123.255  Mask:255.255.255.0

with FS set to a colon character, awk is seeing the leading eleven <space> characters as part of field #1. Maybe you'd get better results with:

 ifconfig eth0 |awk 'BEGIN {FS=" +|:"; printf "IP Address is: "} $2 == "inet" && $3 == "addr" { print $4 }'

which I would expect to produce the output:

IP Address is: 123.123.123.123
2 Likes
awk 'BEGIN {FS=":"; print "IP Address is: "} /inet addr/ { print $2 }'
2 Likes

Hi Don,

Thanks for the explanation. Could you expand a little on the FS=" +|:" part? What are the + and | for?

Joe

--- Post updated at 02:03 PM ---

Thanks for the shorter version, Nezabudka! Im getting some additional output, but I can tweak it.

ifconfig eth0 |awk 'BEGIN {FS=":"; print "IP Address is: "} /inet addr/ { print $2 }'
IP Address is: 
123.123.123.123  Bcast

Joe

As an alternative:

sed -n '/inet addr/ s/.*:\([^ ]\+\).*/IP Address is: \1/p'
2 Likes

YAY, a sed version... Very cool! Thanks!

Hi nezabudka,
Note that with <colon> as the field separator, $2 in the line:

         inet addr:123.123.123.123  Bcast:123.123.123.255  Mask:255.255.255.0

will be 123.123.123.123 Bcast (there are two <space>s between the last "3" and the "B").

Hi Joe,
In awk FS is a variable that contains an extended regular expression (aka ERE) that is used to match strings of one or more characters that are to be treated as field separators. The default value for FS is a single <space> character. That single <space> is an ERE with a special meaning only in awk that tells awk to ignore all leading and trailing <space>, <tab>, and <newline> characters in each record and treat each remaining sequence of one or more <space>, <tab>, or <newline> characters as a field separator. Note that you won't have any <newline> characters in a record if you're using the default record separator variable ( RS ) value (which is a <newline> character).

In an ERE, the <vertical-bar> character ( | ) separates two EREs and if either of those EREs are matched, the matched string is used as a field separator. In an ERE, the <plus-sign> following an ERE matching a single character causes the match to be performed on one or more characters matching the ERE it follows. So in the ERE " +|: ", the ERE before the <vertical-bar> (<space><plus-sign>) matches one or more adjacent <space> characters, the ERE after the <vertical-bar> (<colon>) matches exactly one <colon> character. And, with FS set this way, the input line:

          inet addr:123.123.123.123  Bcast:123.123.123.255  Mask:255.255.255.0

will be split into fields as follows:
Field #1 will be the empty string before the 11 <space> characters at the start of the line, field #2 will be set to inet , field #3 will be set to 123.123.123.123 , field #4 will be set to Bcast , field #5 will be set to 123.123.123.123 , field #6 will be set to Mash , field #7 will be set to 255.255.255.0 , and NF (the awk variable specifying the number of fields in the current input record) will be set to 7.

3 Likes

Hello joeg1484,

Could you please try following once.

awk '/inet addr:/ && match($0,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/){print substr($0,RSTART,RLENGTH)}' Input_file

Thanks,
R. Singh

2 Likes

Hi R. Singh,

Yes that worked as well. Looks a little greek to me, however, but it worked :smiley:

Thanks!
Joe