NeronLeVelu
NeronLeVelu

Reputation: 10039

Trap or evaluate bad regular expression string at runtime in awk script

How can I trap an error if a dynamic regular expression evaluation is bad like:

var='lazy dog'
# a fixed Regex here, but original is coming from ouside the script
Regex='*.'

#try and failed
if (var ~ Regex) foo

The goal is to manage this error as I cannot test the regex itself (it comes from external source). Using POSIX awk (AIX)

Upvotes: 1

Views: 213

Answers (1)

Ed Morton
Ed Morton

Reputation: 203995

Something like this?

$ echo 'foo' |
awk -v re='*.' '
    BEGIN {
        cmd="awk --posix \047/" re "/\047 2>&1"
        cmd | getline rslt
        print "rslt="rslt
        close(cmd)
    }
    { print "got " $0 " but re was bad" }
'
rslt=awk: cmd. line:1: error: Invalid preceding regular expression: /*./
got foo but re was bad

I use gawk so I had to add --posix to make it not just accept that regexp as a literal * followed by any char. You'll probably have to change the awk command being called in cmd to behave sensibly for your needs with both valid and invalid regexps but you get the idea - to do something like an eval in awk you need to have awk call itself via system() or a pipe to getline. Massage to suit...

Oh, and I don't think you can get the exit status of cmd with the above syntax and you can't capture the output of a system() call within awk so you may need to test the re twice - first with system() to find out if it fails but redirecting it's output to /dev/null, and then on a failure run it again with getline to capture the error message.

Something like:

awk -v re='*.' '
    BEGIN {
        cmd="awk --posix \047/" re "/\047 2>&1"
        if ( system(cmd " > /dev/null") ) {
            close(cmd " > /dev/null")
            cmd | getline rslt
            print "rslt="rslt
            close(cmd)
        }
    }
    { print "got " $0 " but re was bad" }
'

Upvotes: 3

Related Questions