-
awk commands inside of a bash script
im pretty sure this is a remedial task for many of you but im having an issue with arrays from a shell script being accessed in an awk command. im pretty good with shell scripting but i am embarrassingly unfamiliar with awk. so here's the meat of the script...
Code:
masks=( "0.0.0.0" "0.0.0.1" "0.0.0.3" "0.0.0.7" "0.0.0.15" "0.0.0.31" "0.0.0.63" "0.0.0.127" \
"0.0.0.255" "0.0.1.255" "0.0.3.255" "0.0.7.255" "0.0.15.255" "0.0.31.255" "0.0.63.255" "0.0.127.255" \
"0.0.255.255" "0.1.255.255" "0.3.255.255" "0.7.255.255" "0.15.255.255" "0.31.255.255" "0.63.255.255" \
"0.127.255.255" "0.255.255.255" "1.255.255.255" "3.255.255.255" "7.255.255.255" "15.255.255.255" \
"31.255.255.255" "63.255.255.255" "127.255.255.255" "255.255.255.255" )
bits=( "32" "31" "30" "29" "28" "27" "26" "25" "24" "23" "22" "21" "20" "19" "18" "17" "16" "15" \
"14" "13" "12" "11" "10" "9" "8" "7" "6" "5" "4" "3" "2" "1" "0" )
if [ $# -lt 3 ]
then
echo "Usage: $0 <Input File (Crump)> <Output File (Blacklist)> <Format (cisco|juniper)>"
fi
awk=`which awk`
input=$1
output=$2
format=$3
if [ $format = "cisco" ]
then
$awk -v null="" 'BEGIN { IFS=" "; IRS="\n"; OFS=" "; ORS="\n"; } { line=0; print "deny ip " $2 " " $3 " " "any"; }' < $input > $output
elif [ $format = "juniper" ]
then
$awk -v masks="$masks" -v bits="$bits" 'BEGIN { IFS=" "; IRS="\n"; OFS=" "; ORS="\n"; }
{ line=0;
for (i=0; i<=31; i++ ) {
if($3 == "${masks[$i]}")
{
break;
}
}
print "\t" $2 "/" ${bits[$x]};
}
' < $input > $output
fi
echo "DONE!"
i am trying to take an input file of ip addresses and corresponding netmasks and put it into a format to be loaded onto a juniper switch. the result should look something like this.. x.x.x.x/netmask using the cidr notation. no matter what subnet is provided though, /32 always gets appended to the end of the ip even when it should be /16, /24, etc... also, the cisco part works fine so that doesnt need any attention.
any ideas on what i'm doing wrong?
-
Not sure how much of help this can be, but I find this alot easier....
cat 1.txt | perl -e use Net::CIDR; print join("\n", Net::CIDR::range2cidr(<STDIN>));
1.txt:
192.168.0.1-192.168.0.100
192.168.1.0-192.168.1.50
You can also make it work with netmask, doc has examples:
http://search.cpan.org/~mrsam/Net-CIDR-0.11/CIDR.pm
-
-
i was setting x=i inside the awk script to see if i could then use it in the print statement. after trying a few different things, i decided to post here and just edited the code to reflect what i had originally, apparently forgetting to remove the $x.
-
Well I don't really understand awk (I only read the first half of "sed and awk") so I might be missing something here but I had to make some changes to get the script to run at all.
For a start with the script as written I got the following error:
Code:
awk: cmd. line:8: print "\t" $2 "/" ${bits[$i]};
awk: cmd. line:8: ^ syntax error
so I had to go away and read up on arrays and find that the thing to do was to split the list of masks and bits into an actual array.
Code:
{ line=0;
split(masks, maskarray);
split(bits, bitarray);
for (i=0; i<=31; i++ ) {
if($3 == maskarray[i])
{
break;
}
}
print "\t" $2 "/" bitarray[i];
}
On top of all that you declared the masks and bits lists as bash arrays but since awk is interpreting them as strings you can't just say
Code:
awk -v masks="$masks" bits="$bits"
Instead you need to say
Code:
awk -v masks="${masks[*]}" -v bits="${bits[*]}"
That's definitely enough awk for one day.
-
i knew there had to be a way to do what i wanted! in all of my googling i didnt come across that split function once, or how to initialize arrays for use inside of awk. after making your changes this seems to work! at least i was on the right track! thanks for your help!
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
|