0

Good day,

Your kind help on this issue will be highly appreciated. Im new to this stuff and I did try to research on how to correctly execute this but I cant make it to work so far. I have several map files which I filter using grep commands to extract violation messages like so:

grep "SoftBin 404" wmap*CP2
wmap_01_CP2:DISP_OB:    SoftBin 404 is 11 dice exceeded Bin Reject Control limit of 11 dice
wmap_03_CP2:DISP_OB:    SoftBin 404 is 11 dice exceeded Bin Reject Control limit of 11 dice
wmap_17_CP2:DISP_OB:    SoftBin 404 is 13 dice exceeded Bin Reject Control limit of 11 dice
grep "SoftBin 418" wmap*CP2
wmap_01_CP2:DISP_OB:    SoftBin 418 is 22 dice exceeded Bin Reject Control limit of 20 dice
wmap_02_CP2:DISP_OB:    SoftBin 418 is 32 dice exceeded Bin Reject Control limit of 20 dice
wmap_03_CP2:DISP_OB:    SoftBin 418 is 48 dice exceeded Bin Reject Control limit of 20 dice
wmap_04_CP2:DISP_OB:    SoftBin 418 is 43 dice exceeded Bin Reject Control limit of 20 dice

Now I want to filter only those messages with fail count of more than 25. I was able to do that using awk :

grep "SoftBin 404" wmap*CP2 | awk '$5>25'

The above returned no result since the maps has fail qty (on column 5) of only 11,11 and 13 which is less than 25.

grep "SoftBin 418" wmap*CP2 | awk '$5>25'
wmap_02_CP2:DISP_OB:    SoftBin 418 is 32 dice exceeded Bin Reject Control limit of 20 dice
wmap_03_CP2:DISP_OB:    SoftBin 418 is 48 dice exceeded Bin Reject Control limit of 20 dice
wmap_04_CP2:DISP_OB:    SoftBin 418 is 43 dice exceeded Bin Reject Control limit of 20 dice

Now I want to put this in a bash script using if else statement but im having trouble getting the else part to work. Here is my script:

more test.sh 
#! /bin/bash 

printf "\n"
SB404=$(grep -q "Softbin 404" wmap*CP2 | awk '$5>25')
SB404_stat="$?"
if [ "$SB404_stat" -eq 0 ] ; then
   echo "Softbin 404 for reprobe" ; grep "SoftBin 404" wmap*CP2 | awk '$5>25'
else
   echo "No Softbin 404 for reprobe"
fi
printf "\n"
SB418=$(grep -q "Softbin 418" wmap*CP2 | awk '$5>25')
SB418_stat="$?"
if [ "$SB418_stat" -eq 0 ] ; then
   echo "Softbin 418 for reprobe" ; grep "SoftBin 418" wmap*CP2 | awk '$5>25'
else
   echo "No Softbin 418 for reprobe"
fi
printf "\n"

I got the grep -q part on one of forums I read and applied it, but Im not sure if its enough since I still have the awk part which will dictate the final result of that line. I know Im missing something or I just had it plain wrong. Here's my output:

./test.sh 

Softbin 404 for reprobe

Softbin 418 for reprobe
wmap_02_CP2:DISP_OB:    SoftBin 418 is 32 dice exceeded Bin Reject Control limit of 20 dice
wmap_03_CP2:DISP_OB:    SoftBin 418 is 48 dice exceeded Bin Reject Control limit of 20 dice
wmap_04_CP2:DISP_OB:    SoftBin 418 is 43 dice exceeded Bin Reject Control limit of 20 dice

Apology if this is too long, I just want to make my issue as clear as possible. Appreciate in advance all the help you can share. Thanks again.

Mike

2
  • awk doesn't return and exit indicating error, try with this echo "hello world" | awk '/Hello/' and print the exit code echo $?
    – c4f4t0r
    Commented Jul 15, 2020 at 10:26
  • yes you are right, thanks for the comment, still in the learning process.
    – Mike
    Commented Jul 15, 2020 at 10:35

2 Answers 2

1

There were couple of mistakes in your code. I am trying to fix it with minimum changes to your code.

  1. grep -q will provide if the result is available or not like 0 or 1 so you can directly use them on if however you are piping that output to awk then it will only use the 0/1 as its input not the whole line.

  2. grep without an option i is case sensitive. you are searching for Softbin and not SoftBin which is available in the file.

printf "\n"
SB404_stat=$(grep "SoftBin 404" wmap*CP2 | awk '$5>25'| wc -l)
if [ $SB404_stat -ne 0 ] ; then
   echo "Softbin 404 for reprobe" ; grep "SoftBin 404" wmap*CP2 | awk '$5>25'
else
   echo "No Softbin 404 for reprobe"
fi
printf "\n"
SB418_stat=$(grep "SoftBin 418" wmap*CP2 | awk '$5>25' | wc -l)
if [ $SB418_stat -ne 0 ] ; then
   echo "Softbin 418 for reprobe" ; grep "SoftBin 418" wmap*CP2 | awk '$5>25'
else
   echo "No Softbin 418 for reprobe"
fi
printf "\n"

Result

No Softbin 404 for reprobe

Softbin 418 for reprobe
wmapaCP2: SoftBin 418 is 32 dice exceeded Bin Reject Control limit of 20 dice
wmapaCP2: SoftBin 418 is 48 dice exceeded Bin Reject Control limit of 20 dice
wmapaCP2: SoftBin 418 is 43 dice exceeded Bin Reject Control limit of 20 dice

0
1

Your code uses:

SB404=$(grep -q "Softbin 404" wmap*CP2 | awk '$5>25')
SB404_stat="$?"
if [ "$SB404_stat" -eq 0 ] ; then
  • grep is case-sensitive (you searched for "Softbin" but only "SoftBin" appears in your input, so no output will be produced
  • grep -q produces no output, so awk sees nothing
  • $? is the return value of the most recently executed program (in this case the final program in the pipeline - awk), however awk does not return non-zero just because the condition wasn't met

You could do something like:

SB404=$(grep "SoftBin 404" wmap*CP2 | awk '$5>25{exit 1}'
SB404_stat="$?"
if [ "$SB404_stat" -eq 1 ]; then

However, this is ugly. Also:

  • you invoke awk multiple times to do the same thing
  • you invoke grep to do something that awk can already do
  • awk can also do the printf

script.awk

$2=="SoftBin" && $3==n && $5>25 {
    if (!e++) printf "\nSoftbin %s for reprobe\n", n
    print
}
END {
    if (!e) printf "\nNo Softbin %s for reprobe\n", n
}

test2.sh

#! /bin/bash

awk -f script.awk -v n=404 wmap*CP2
awk -f script.awk -v n=418 wmap*CP2
printf "\n"

This code still scans the wmap*CP2 files twice (but better than the four scans of the original). Depending on the ordering of the files and the desired output, you might be able to just scan once. For example:

script2.awk

BEGIN {
    split(n,t,",")
    for (i in t) b[ t[i] ]++
}
$2=="SoftBin" && $3 in b && $5>25 {
    if (!e[$3]++) printf "\nSoftbin %s for reprobe\n", $3
    print
}
END {
    for (i in b)
        if (!e[i])
            printf "\nNo Softbin %s for reprobe\n", i
    printf "\n"
}

test3.sh

#!/bin/bash

awk -f script2.awk -v n=404,418 wmap*CP2

1
  • Thanks @jhnc, i will study these codes and apply it in mine, actually I still have a few more "SoftBins" to search, I just gave 2 as sample. Still learning this stuff, thanks again.
    – Mike
    Commented Jul 15, 2020 at 11:01

Not the answer you're looking for? Browse other questions tagged or ask your own question.