Print line if values in fields matches number and text

datafile:

2017-03-24 10:26:22.098566|5|'No Route for Sndr:RETEK RMS      00040      /ZZ Appl:PF Func:PD Txn:832    Group Cntr:None ISA CntlNr:None Ver:003050      '|'2'|'PFI'|'-'|'EAI_ED_DeleteAll'|'EAI_ED'|NULL|NULL|NULL|139050594|ActivityLog|
2017-03-27 02:50:02.028706|5|'No Route for Sndr:RETEK RMS      00040      /ZZ Appl:PF Func:PD Txn:832    Group Cntr:None ISA CntlNr:None Ver:003050      '|'2'|'PFI'|'-'|'EAI_ED_DeleteAll'|'EAI_ED'|NULL|NULL|NULL|139188896|ActivityLog|

I need a awk command that will output the lines from a log, if the number in column 4 is equal to 2 AND the text in column 8 contains "EAI_ED". The fields from the log are separated by Pipes.

here's my attempt awk attempt:

COLUMNANum=4
COLUMNANumVal=2

COLUMNBText=8
COLUMNBTextVal=EAI_ED

awk -F"|" '{split($0,a,"|"); gsub("\'", "", a[1]);
        if ( $'$COLUMNA' ~ a[1]) &&  ( $'$COLUMNB' ~ a[8]) 
                { print ; w++ }
        else if ($'$COLUMNA' ~ '$CRIT')
                { print ; c++ }
        else { o++}} END {
                printf("%d:OK %d:WARNING %d:CRITICAL\n", o, w, c)
        }' ${LOGFILE}

How about

awk -F"|" '

($C1 == V1) && ($C2 ~ V2)

' C1="$COLUMNANum" V1="$COLUMNANumVal" C2="$COLUMNBText" V2="$COLUMNBTextVal"   file
1 Like

this doesnt seem to work and i think its because there is single quotes surrounding number in column 4.

Try to relieve the condition a bit: $C1 ~ V1 (may yield false positives) or put regex differently $C1 ~ "^."V1".$"

1 Like

it loooks like im still having problems with this.

considering this particular code is part of a larger work that im working on, i need to be able to accomplish what i need using the following line of thinking:

COLUMNANum=4
COLUMNANumVal=2
COLUMNBText=8
COLUMNBTextVal=EAI_ED

awk -F"${SEPARATOR}" -v STRING="EAI_ED" '{split($0,a,"|"); gsub("'\''", "", a[8]) ; gsub("'\''", "", a[4])
        if (( a['$COLUMNANum'] == '${COLUMNANumVal}' ) && ( STRING ~ a['${COLUMNBText}'] ))
                   { print ; c++ }

        else
                { o++ }
        } END {
                printf("%d:OK %d:WARNING %d:CRITICAL\n", o, w, c)
        }' ${LOGFILE}

The above works but when I add bogus text to the end of text "EAI_ED" like this "EAI_EDi", the code still outputs the lines.

i believe my problem is in the bolded. can someone help me straighten this out?

Why that crooked logics? What advantages do you expect from splitting the line into that a array over using the respective fields directly? Why do you pass STRING the correct way and not the other variables?
The ~ operator matches occurrences of substrings, so an concatenated "i" won't stop the matching.

im doing the splitting because, the column that contains the value i need have single quotes in them. so i needed a way to get rid of the single quotes from the specific column i was interested in.

i apologize if im making this necessarily complicated. if i can resolve the issue i bolded, i can move on from this problem.

If the fields in your file are sometimes single-quoted and are sometimes unquoted and you want to print the selected lines from your file as they appear in the input file (obviously wild assumptions since no sample of the desired output has been provided), everything that you are doing seems extremely complicated when the task seems so simple. The fact that your awk samples are using undefined shell variables and that your awk code changes with every post contributes to the confusion.

Does the following (based on your code in post #5 in this thread) come close to what you're trying to do:

#!/bin/ksh
COLUMNANum=4
COLUMNANumVal=2
COLUMNBText=8
COLUMNBTextVal=EAI_ED

# Define variables that were undefined in original code...
SEPARATOR='|'
LOGFILE=${1:-datafile}

# Define awk variables from shell variables and run the code:
awk -v FANum="$COLUMNANum"	-v FAPat="^'?$COLUMNANumVal'?\$" \
    -v FBNum="$COLUMNBText"	-v FBPat="^'?$COLUMNBTextVal'?\$" \
    -F"$SEPARATOR" '
{	if($FANum ~ FAPat && $FBNum ~ FBPat) {
		print
		c++
	} else	o++
}
END {	# Note that w is never set, so there will always be 0 warnings.
	printf("%d:OK %d:WARNING %d:CRITICAL\n", o, w, c)
}' "$LOGFILE"

Note that the patterns used for matching fields A and B ( FAPat and FBPat , respectively) are anchored at both ends and allow 0 or 1 single quote at the beginning and end of the field being matched. With the sample data provided in post #1, this script produces the output:

2017-03-24 10:26:22.098566|5|'No Route for Sndr:RETEK RMS      00040      /ZZ Appl:PF Func:PD Txn:832    Group Cntr:None ISA CntlNr:None Ver:003050      '|'2'|'PFI'|'-'|'EAI_ED_DeleteAll'|'EAI_ED'|NULL|NULL|NULL|139050594|ActivityLog|
2017-03-27 02:50:02.028706|5|'No Route for Sndr:RETEK RMS      00040      /ZZ Appl:PF Func:PD Txn:832    Group Cntr:None ISA CntlNr:None Ver:003050      '|'2'|'PFI'|'-'|'EAI_ED_DeleteAll'|'EAI_ED'|NULL|NULL|NULL|139188896|ActivityLog|
0:OK 0:WARNING 2:CRITICAL

As always, if you want to try this on a Solaris/SunOS system, change awk in the script to /usr/xpg4/bin/awk or nawk .

1 Like