Problem using if else in awk

Hi, i am using Solaris ksh shell, i have a file processed from one of the processes as :

List00 contains the objects within it, with rightmost column(i.e 6th column) denoting the state of entire list or the object. I wanted to assign a status to the List00 using a function chkstate () as:

chkstate () {
name=$( cat file | awk 'NR==1 { print $1 }' );
state=$( cat file | awk 'NR==1 { if ( $6=="AC" || $6=="WA" ) print "Waiting"; else print"NA" }' );
if [[ "${state}" == "NA" ]]; then
state=$( cat file | grep .FW. | awk '{if ( $6=="WO" ) print"Watching"; else print"NA"}' );
fi
if [[ "${state}" == "NA" ]]; then
state=$( cat file | grep -v .FW. | grep -v List* | grep -v '^$' | awk '{ if ( $6=="WO" ) print "InProgress"; else print"NA" }' );
fi
if [[ "${state}" == "NA" ]]; then
state=$( cat file | grep -v .FW. | grep -v List* | grep -v '^$' | awk '{ if ( $6=="CO" ) print "Completed"; else print"NA" }' );
fi
echo "from chkstate () ";
echo $name;
echo $state;
}

the Constraints are:

As you can see, i do have a code but its badly optimized. I tried break in if inside awk but that too dint work well for me. Presently i m doing this manually but that's a hectic job to do as i have many such Lists to
analyse. Can someone please help me to optimize the function suited to the constraints, that would be a great help !!!

mute@thedoctor:~/temp/pr5439$ ./script
Watching

this is the code... i think it's right... :wink:

mute@thedoctor:~/temp/pr5439$ cat script
chkstate() {
        awk '
                NR==1 && ($NF == "AC" || $NF == "WA") {
                        state="Waiting"
                        exit
                }
                ($1 ~ /^objFW/) && ($NF == "WO") {
                        state="Watching"
                        exit
                }
                ($1 !~ /^objFW/) {
                        obj++
                        if ($NF == "WO") objWO++
                        if ($NF == "CO") objCO++
                }
                END {
                        if (!state) {
                                if (objCO == obj)
                                        state="Completed"
                                else if (objWO > 0)
                                        state="InProgress"
                                else
                                        state="NA"
                        }
                        print state
                }' "$1"
}

chkstate file
1 Like

thanks neutronscott, your code seems to solve most of it, but one logic is missed here. May be one of the constraints was not totally explained, i'll elaborate that again:

your code snippet here, ignores WA state of obj003 and obj004 and returns a NA(implies wrong logic if state = NA after all checks) state if all FW objects are CO(completed)

($1 !~ /^objFW/) {
                        obj++
                        if ($NF == "WO") objWO++
                        if ($NF == "CO") objCO++
                }
                END {
                        if (!state) {
                                if (objCO == obj)
                                        state="Completed"
                                else if (objWO > 0)
                                        state="InProgress"
                                else
                                        state="NA"
                        }
                        print state
                }' "$1"

I myself will try on that but any help from anyone too is very welcome. i think slight tweak in the conditional part will serve the purpose.

Your description said WO, yet you're now saying WA. Is it WO or WA? I'm not quite sure what we're working with, but it doesn't matter I suppose.

Could you provide the same input that gives the wrong results as well?

here, besides one object working(WO) we have two objects waiting (WA) when all FW objects are completed(CO). Under such a case i must get InProgress state (if any object other than objFW1 and objFW2 is WO then list has a state of InProgress)

It seems to operate correctly here:

mute@thedoctor:~/temp/pr5439$ cat file
List00 11 24 54 32 WO
obj001 06 01 00 02 CO
obj002 01 01 03 00 WO
objFW1 00 01 00 00 CO
obj003 01 04 09 13 WA
objFW2 00 03 02 07 CO
obj004 03 14 30 10 WA
mute@thedoctor:~/temp/pr5439$ ./script
InProgress

One thing that would probably always give an "NA" is improper line endings:

mute@thedoctor:~/temp/pr5439$ ./script
NA
mute@thedoctor:~/temp/pr5439$ file file
file: ASCII text, with CRLF line terminators
mute@thedoctor:~/temp/pr5439$ tr -d '\r' <file >new && mv new file
mute@thedoctor:~/temp/pr5439$ ./script
InProgress
1 Like

Perhaps you are rite. Totally my mistake, after revisiting your code i found there is nothing wrong with the code and is the most elegant solution that can ever be for the situation.

Thanks neutronscott !!!! :slight_smile:

All i knew about awk is that it starts with the first field of first record and progresses till the end of record visiting every field only once. But the execution flow in your solution seems different to me(may be i am wrong). Can u briefly explain if my understanding is correct or not ?

Yes. It only processes each line once, going through a file line-by-line. This is why I have variables keep a count of "other objects" CO and WO. The other requirements are pretty much: If you see this one line, then the answer is known definitely. If those first two requirements aren't met, we look at our variables to see if all "other objects" are completed, else, if any "other object" is WO, and finally, fail with NA..

All the code in the END block is executed at those "exit" statements, or after the last line is read in the file.. This is when we decide the state, if one hasn't already been decided.

I was rushed (it's quitting time), feel free to ask for more clarification if needed.

i think that would suffice my needs neutronscott, i got my answer.

Thanks again :slight_smile: