Variable assignment inside awk

Hi,

Was hoping someone could help with the following:

while read line; do pntadm -P $line | awk '{if (( $2 == 00 && $1 != 00 ) || ( $2 == 04 )) print $3,$5}'; done < /tmp/subnet_list

Anyone know if it is possible to assign $3 and $5 to separate variables within the {} brackets?

Thanks in advance
CiCa

This will go much faster if you explain what it is you are trying to accomplish. Perhaps demonstrate a failed attempt and explain why it was inadequate.

The answer to your question as asked is an obvious yes. The value of the field variables $3 and $5 can be assigned to separate variables (although they already are in separate variables). Perhaps you meant if those values could be pulled out of AWK and assigned to shell variables?

Again, this will go much faster if you explain the bigger picture.

Regards,
Alister

Hi Alister,

Essentially what I am trying to get here is pick out list of IP addresses from dhcp pool on a Solaris (dhcp) server where certain criteria are matched.

/tmp/subnet_list - contains a list of subnets

The pool for each subnet is listed and each line (containing an IP address among other details) is checked.

I am trying to match each line that has a MAC address present AND a reserved flag of 00 (awk variables $1 and $2 respectively) OR has a reserved flag of 04 (again awk variable $1).

For each of the lines that are matched, I want to pass the awk variables $3 and $5 (of the line in question) out to a shell variable e.g. ip_address=$3 and lease_date=$5. So I can then pass these through another check...

I hope this helps explain things a little better and unfortunately I can not provide code examples at this point in time, as I do not have access to the script from the system I am presently using.

If further details are required, let me know...

Thanks in advance
CiCa

Here's a possible way, in a shell script:

rm -f /tmp/awk_output
while read line; do
  pntadm -P $line | awk '{if (( $2 == 00 && $1 != 00 ) || ( $2 == 04 )) print $3,$5}' >> /tmp/awk_output
done < /tmp/subnet_list

while read ip_address lease_date; do
  echo $ip_address lease_date
  # further ops
done < /tmp/awk_output

Thanks Hanson44 - I could do it that way, but I was really hoping to assign $3 and $5 to shell variables inside the {} brackets (assuming that it is actually possible?)...

Just to make the picture a little clearer:

root[my-box]# cat /tmp/final_list
111.222.333.0
root[my-box]# pntadm -P 111.222.333.0 | head

Client ID       Flags   Client IP       Server IP       Lease Expiration                Macro           Comment

00A0BCDE1FGHI1  00      111.222.333.001    111.222.333.253     04/06/2013                      macro1
00              04      111.222.333.002    111.222.333.253     Zero                            macro1
00              00      111.222.333.003    111.222.333.253     Zero                            macro1
00A0BCDE1FGHI2  00      111.222.333.004    111.222.333.253     05/06/2013                      macro1
root[my-box]#

Present code:

while read line; do pntadm -P $line | awk '{if (( $2 == 00 && $1 != 00 ) || ( $2 == 04 )) print $3,$5}'; done < /tmp/subnet_list

The code I have a present should pick out three lines from above (IP's 111.222.333.001 ...002 and ...004).

Can anyone tell me how to assign $3 and $5 to shell variables, within the {} brackets - please? :slight_smile:

Rgds
CiCa

Use array

while read line; do 
  val=( pntadm -P $line | awk '{if (( $2 == 00 && $1 != 00 ) || ( $2 == 04 )) print $3,$5}' )
  echo ${val[0]} ${val[1]}
done < /tmp/subnet_list

--ahamed

Thanks Ahamed101 - unfortunately though, my knowledge around arrays and their usage is pretty limited e.g. how do I then read these values out of the array?

Alternatively, do you know of a way of doing this without the use of an array?

Thanks
CiCa

I have already given the way to read the values from array. Check the echo statement.

--ahamed

I just Googled array usage and then realised that too - my mistake. :o

Although have I missed a | in the following:

root[my-box]# while read line; do 
val=(pntadm -P $line | awk '{if (( $2 == 00 && $1 != 00 ) || ( $2 == 04 )) print $3,$5}') 
echo ${val[0]} ${val[1]}; done < /tmp/final_list
bash: syntax error near unexpected token `|'
root[my-box]#

I am not sure about the error, i think your OS is solaris - I see pntadm. Try using nawk.

--ahamed

ok - thanks.

Back to my original question then - anyone know if there is a way to assign $3 and $5 to shell variables inside the {} brackets...

Thanks in advance
CiCa

Did you try nawk?
Another way -

val=$( pntadm... )
ip=${val% *}
time=${val#* }

--ahamed

1 Like

Ahh haa - it was the $ sign in val=$ that I needed...

This looks to be a good starting point to let me proceed with the rest of the script - thanks ahamed101.

Just out of curiosity, can you explain why you've put val% * and val#* in the following:

val=$( pntadm... )
ip=${val% *}
time=${val#* }

They are shell string substitutions. The output from the pntadm statement results into IP address and Expiry date separated by space.

ip=${val% *} will remove everything from behind till it encounters a space i.e. it will remove the expiry date
time=${val#* } will remove everything from front till it encounters a space i.e. it will remove the IP address

--ahamed

Well, if you could do it that way, then what's the problem? :slight_smile: