Search code examples
linuxbashparsingawkcurly-braces

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


Solution

  • using gawk

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

    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 "%s, %s",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