We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

Bash shell variable not passed into AWK reg expression

Medium Priority
899 Views
Last Modified: 2012-05-07
Hello,

I am able to succesfully pass a shell variable into a AWK reg expression  if the shell variable is explicitely defined. (In the code below if I uncomment  #pattern="INTEGER: 4"  everything works)  

However when the variable is implicitely defined (via the code : pattern=`awk ....)  [and  "pattern="INTEGER: 4" is commented]  I  am not getting any match.

Can this be done?

Thank you

PA

echo "Regular Expression:"
d="4/1"
pattern=`awk '/ifDescr/ {print $0}' MIBDump |  awk -F',' -v test1="$d" '$0 ~ test1 { print "INTEGER: " substr($1,9,2) }'`
echo $pattern # to check that the reg expression is formed correctly. This is working as expected.
 
#pattern="INTEGER: 4"
#  If I uncomment, the filter below works. If I leave it commented, the filter below does not return any match.
 
echo "Filter:"
awk -F',' -v test2="$pattern" '$0 ~ test2 { print $0 }' /home/pguanel/MIBDump
# I am using the variable "pattern" defined earlier to do my reg expression
 
 
!  The releavant section of the file "MIBDump" 
 
# Interface Description (ifDescr):
ifDescr.1 = STRING: Ethernet0/0
ifDescr.2 = STRING: GigabitEthernet0/0
ifDescr.3 = STRING: FastEthernet4/0
ifDescr.4 = STRING: FastEthernet4/1
ifDescr.6 = STRING: Null0
ifDescr.7 = STRING: E1 2/0
ifDescr.8 = STRING: E1 2/1
ifDescr.9 = STRING: E1 2/2
ifDescr.10 = STRING: E1 2/3
ifDescr.11 = STRING: E1 2/4
enterprises.9.9.166.1.1.1.1.4.68683 = INTEGER: 27
enterprises.9.9.166.1.1.1.1.4.102973 = INTEGER: 4  
enterprises.9.9.166.1.1.1.1.4.103221 = INTEGER: 2
 
! Result should be : 102973

Open in new window

Comment
Watch Question

Peter KwanAnalyst Programmer

Commented:
1. Please check whether your files /home/pguanel/MIBDump  (line 10) and MIBDump (line 3) are referring to the same file.
2. Please see the following works:

awk -F',' -v test2="$pattern" '$0 ~ test2 { print $0 }' MIBDump



Author

Commented:
pkwan, I have changed the path on line 10 as suggested, but no result.

All the files are in my  home directory (script and MIBDump file) so the discrepency did not matter here.

thank you

PA
its better to show your input file as well as  show how your final output file will look like. From your code, i don't see where the comma delimiter is.

Author

Commented:
ghostdog74,

there is no comma delimiters in my input file, but since I am doing the reg expression on the first collumn any way , it does not matter.  

Here is the output when I remove the comment  on #pattern="INTEGER: 4". You can see that the bash variable is correctly used by the filter.

Regular Expression:
INTEGER: 4    # This is the result of the first Regular expresssion
Filter:
enterprises.9.9.166.1.1.1.1.4.102973 = INTEGER: 4  # this is the result of the filter


Here is the output when I leave the comment

Regular Expression:
INTEGER: 4   # This is the result of the first Regular expresssion
Filter:         # nothing there ....


Input file and script attached as per your request.

It seems as though when the bash variable is the result of a previous awk, it does not work.

Also I tried to set the bash variable interractively using the "read" command,  it also worked correctly ...


PA
MIBDump
attempt02
i am not interested in how you get your results. I am only interested in how your actual output file will look like . ie what do you exactly want to get from your input file. Show it exactly.

Author

Commented:
Hi ghostdog74

What I want to get is the value : 102973 as seen from line 28 of the snipet : enterprises.9.9.166.1.1.1.1.4.102973 = INTEGER: 4  

The process should be as follows: start from a known interface description (here it is d$), then awk to find the index value of the interface  (here it is 4) , store that value into a variable after adding some characters (my variable is "pattern"), then use that variable in another reg expression to derive the final MIB index value (102973). ...

This needs to be done dynamically ...

Thanks

PA

Analyst Programmer
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Author

Commented:
pkwan and ghostdog74, your solutions both work.

pkwan's solution is easier to understand given my novice level. Just a point of curiosity though, is there a way in shell to see spaces and other hidden characters  (like in word you can toggle a special mode to see spaces, end of line , carriage return etc ...) ?

ghostdog74, your solution looks very compact but a bit over my head (I am just starting to learn awk). If you could give me a brief explanation of your code to get me started I will be most grateful...

Anyway I am accepting both of your solutions.

Thanks again for your help.

PA

Author

Commented:
Please see comments on the solution  above.

Many thanks

PA
@OP
Please read the GAwk manual on how awk works.


awk 'BEGIN{
 #initialize variables
 pat="4/1"
 #set field separator as "=" , ":" and space
 FS="[=: ]"
}
/ifDescr/ && $0~pat {
     # if ifDescr is found and contains "4/1"
     # substitute from start of line till the last "." of column 1
     gsub(/.*\./,"",$1)     
     pattern="INTEGER: "$1
     #val should be 4
     val=$1     
     f=1 #set flag to indicate that "4" is found
}
f && /INTEGER/ && $NF==val {    
    #if "found" and line contain the word INTEGER and the last column($NF) is "4"
    m=split($1,t,".") #split the first column on dots "."
    #then get the last element which is what you want
    print t[m]
    f=0
}' MIBDump

Open in new window

Author

Commented:
Thanks ghostdog74 !
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.