What is wrong with my awk command?

The below code usually works when the value for the COLUMN variable is numerical. but im in a situation where the number of fields in a file is not definitive. it changes.
but what is static is that the value i want to retrieve from the log is 3 fields from the last field. which is what i attempted to grab with the '(NF-3)'

data:

costingi.PrimaryCost query {"costType": 1, "season": 1, "year": 1} 1 500 500 500 n/a 1
planningservice.targets query {"ccId": 1, "inDCDate": {"$ne": 1}, "season": 1, "year": 1} 1 160 160 160 n/a 1

code:

WARN=170
CRIT=200
COLUMN='(NF-3)'

awk -F" " '/query/ && !/nothing/ {if($'$COLUMN' = '$WARN' || $'$COLUMN' = '$CRIT') { print ; w++ } else if($'$COLUMN' = '$CRIT') { print ; c++ } else {o++}} END { printf("%d:OK %d:WARNING %d:CRITICAL\n", o, w, c) }'

However, when i run the above command, it simply outputs everything in the file, instead of just the specific lines that have a value greater than the

Hello SkySmart,

Variable defining in awk doesn't work like in SHELL, could you please change you code to following and let me know if this helps.

awk -vwarn="$WARN" -vcrit="$CRIT" -vcolumn="$COLUMN" -F" " '/query/ && !/nothing/ {if($column = warn || $column = crit) { print ; w++ } else if($column = crit) { print ; c++ } else {o++}} END { printf("%d:OK %d:WARNING %d:CRITICAL\n", o, w, c) }'

Also as you haven't provided any sample Input_file or expected output so I haven't tested it at all.

Thanks,
R. Singh

1 Like

you cannot do it like this - you cannot expect the COLUMN be evaluated at run time.
consider the following - not aligned/tested:

WARN=170
CRIT=200
COLUMN=3
awk -v col="${COLUMN}" -v warn="${WARN}" -v crit="${CRIT}" '
/query/ && !/nothing/ {
   if($(NF-col) == warn ||  $(NF-col) == crit) 
    {print ; w++ } 
  else if($(NF-col) == crit) 
   {  print ; c++ } 
  else o++
}
END { printf("%d:OK %d:WARNING %d:CRITICAL\n",  o, w, c) }'
1 Like

unfortuntely, none of the suggested commands work.

i need to be able to specify the column to look into. most columns are counted from left to right. however, due to spaces/tabs or formatting differences in files, one may want to grab a column based on the count of right to left.

The solution i need should be able to take a regular numerical value AND also a value like "(NF-whateverNUmber)" which means, count from right to left.

The full data file looks like this:

costingintegration.ExceptionLogEntry     query         {"_id": 1, "retryFlag": {"$ne": 1}}            1     3778     3778      3778    n/a          3778
costingintegration.negotiatedProductCosts   query         {"$and": [{"season": 1}, {"year": 1}]}            9      138      735       410    n/a          3696
costingintegration.negotiatedProductCosts   query         {"brand": 1, "season": 1, "year": 1}              6      109     2447       534    n/a          3208
costingintegration.$cmd            count         {"costType": 1, "season": 1, "year": 1}           2     1151     1536      1343    n/a          2687
costingintegration.PrimaryCost        query         {"season": 1, "year": 1}                    2      271     1905      1088    n/a          2176
costingintegration.negotiatedProductCosts   getmore       {"$and": [{"season": 1}, {"year": 1}]}           11      104      353       148    n/a          1630
masteritem.$cmd      findandmodify    {"_id": 1}                 1     1451     1451      1451    n/a          1451
costingintegration.$cmd            count         {"season": 1, "year": 1}                    1     1012     1012      1012    n/a          1012
costingintegration.PrimaryCost        query         {"costType": 1, "season": 1, "year": 1}           1      500      500       500    n/a          500
costingintegration.PrimaryCost        getmore       {"bomCCNumber": 1, "season": 1, "year": 1}                      1      252      252       252    n/a          252
planningservice.targets            query         {"ccId": 1, "inDCDate": {"$ne": 1}, "season": 1, "year": 1}           1      160      160       160    n/a          160
costingintegration.$cmd            count         {"brand": 1, "season": 1, "year": 1}              1      136      136       136    n/a          136

in other words, based on the log file, sometimes, i may need the value of COLUMN to be "4" meaning grab column $4. Or if the format of the log is unusual, i may need to say, grab the 3rd column from the right. so essentially, i need to be able to specify:

COLUMN=4
or
COLUMN='(NF-3)'

try this and pass -v col="${COLUMN}" as you see fit where COLUMN is either positive or negative (either 4 or -3 in your example):

/query/ && !/nothing/ {
  cn=(col>0)?col:NF+col
  if($cn == warn ||  $cn == crit)      
    {print ; w++ }    
  else if($cn == crit)     
           {  print ; c++ }    
          else o++ }

Shouldn't that be NF+col if col is negative?

1 Like

good catch, RudiC - fixed.
Thanks

i get back no response when i run this command.

Did you take the proposal in post#3 and adapt it according to post#5? And, you might want to use >= in lieu of == , so you don't need to exactly hit the thresholds...

Plus, I think your logic has a flaw in the first place:
With the OR condition TRUE, w will be incremented, which is fine as a critical value can trigger the warning threshold as well. But, the "critical" section will never be reached, and c never be incremented, as it will have triggered the second of the OR conditions...
Wouldn't sth. like

                 if ($cn >= crit)               {print; c++; w++}    
                 else   if ($cn >= warn)        {print ; w++ }    
                        else                     o++

be better?

2 Likes