PatrikJ PatrikJ - 2 months ago 7
Linux Question

Config parsing with awk

I am trying to learn some awk magic and I am trying to parse data according to these rules:

If the allow-service section contains default, https:any, all, ssh:any, ssh:tcp I wish to output the interface name and the matched services on one line per non-compliant interface.

The data I have looks something like this:

net self interface1 {
allow-service none
}
net self interface2 {
allow-service none
}
net self interface3 {
allow-service {
icmp:any
}
}
net self interface4 {
allow-service {
icmp:any
}
}
net self interface5 {
allow-service {
icmp:any
default
}
}
net self interface6 {
allow-service all
}
net self interface7 {
allow-service {
icmp:any
8888:tcp
9999:any
}
}
net self interface8 {
allow-service {
icmp:any
default
}
}
net self interface9 {
allow-service {
https:any
ssh:any
icmp:any
}
}
net self interface10 {
allow-service {
icmp:any
default
}
}


The output I wish to get is something like this:

interface5, default
interface6, all
interface8, default
interface9, https:any, ssh:any
interface10, default


Additional conditions:


  • It must be a oneliner

  • I can't use a bash script, but I can use bash commands

  • It must end with an awk script



Pretty peculiar limitations, I know.

I started poking around a bit and found this to give me only the data in the allow service section, but it will be showing trailing "}" and I have not figured out how to save the interface name:

awk 'BEGIN {RS="net self [A-Za-z0-9_]+ {\n[ ]+";ORS="=";}{print;}'


Any help or push in the right direction is much appreciated!

/Patrik

Answer

using gawk

awk -F" " -v RS="{|}|allow-service|\n"  '/(https|ssh):any|all|default/{printf prev", "$1;prev="";u=2} /net self/{prev=$3} /net self/&&u==2{u=0;printf "\n"}' file

or

awk -F" " -v RS="{|}|allow-service|\n"  '/(https|ssh):any|all|default/{printf p", "$1;p=""} /net self/{printf "\n";p=$3}'file  | awk 'NF{print}'

output

interface5, default
interface6, all
interface8, default
interface9, https:any, ssh:any
interface10, default

breakdown

    -F" " 
    RS="{|}|allow-service|\n"  
   '/(https|ssh):any|all|default/{printf prev", "$1;prev="";u=2} # print the values and set u-used to 2
    /net self/{prev=$3} #store interface
    /net self/&&u==2{u=0;printf "\n"} #print tags in new-line
Comments