Home > Mobile >  Need of awk command explaination
Need of awk command explaination

Time:02-02

I want to know how the below command is working.

awk '/Conditional jump or move depends on uninitialised value/ {block=1} block {str=str sep $0; sep=RS} /^==.*== $/ {block=0; if (str!~/oracle/ && str!~/OCI/ && str!~/tuxedo1222/ &&  str!~/vprintf/ && str!~/vfprintf/ && str!~/vtrace/) { if (str!~/^$/){print str}} str=sep=""}' file_name.txt >> CondJump_val.txt

I'd also like to know how to check the texts Oracle, OCI, and so on from the second line only. 

CodePudding user response:

The first step is to write it so it's easier to read

awk '
    /Conditional jump or move depends on uninitialised value/ {block=1}
    block {
        str=str sep $0
        sep=RS
    }
    /^==.*== $/ {
        block=0
        if (str!~/oracle/ && str!~/OCI/ && str!~/tuxedo1222/ &&  str!~/vprintf/ && str!~/vfprintf/ && str!~/vtrace/) {
            if (str!~/^$/) {
                print str
            }
        }
        str=sep=""
    }
' file_name.txt >> CondJump_val.txt

It accumulates the lines starting with "Conditional jump ..." ending with "==...== " into a variable str. If the accumulated string does not match several patterns, the string is printed.

I'd also like to know how to check the texts Oracle, OCI, and so on from the second line only.

What does that mean? I assume you don't want to see the "Conditional jump..." line in the output. If that's the case then use the next command to jump to the next line of input.

    /Conditional jump or move depends on uninitialised value/ {
        block=1
        next
    }

CodePudding user response:

perhaps consolidate those regex into a single chain ?

if (str !~ "oracle|OCI|tuxedo1222|v[f]?printf|vtrace") {

    print str
}

CodePudding user response:

There are two idiomatic awkisms to understand.

The first can be simplified to this:

$ seq 100 | awk '/^22$/{flag=1} 
/^31$/{flag=0} 
flag' 
22
23
...
30

Why does this work? In awk, flag can be tested even if not yet defined which is what the stand alone flag is doing - the input is only printed if flag is true and flag=1 is only executed when after the regex /^22$/. The condition of flag being true ends with the regex /^31$/ in this simple example.

This is an idiom in awk to executed code between two regex matches on different lines.

In your case, the two regex's are:

/Conditional jump or move depends on uninitialised value/  # start
# in-between, block is true and collect the input into str separated by RS
/^==.*== $/   # end

The other 'awkism' is this:

block {str=str sep $0; sep=RS}

When block is true, collect $0 into str and first time though, RS should not be added in-between the last time. The result is:

str="first lineRSsecond lineRSthird lineRS..."

both depend on awk being able to use a undefined variable without error

  • Related