Reputation: 85
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
Upvotes: 0
Views: 589
Reputation: 16662
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 producedgrep -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 metYou 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:
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
Upvotes: 1
Reputation: 944
There were couple of mistakes in your code. I am trying to fix it with minimum changes to your code.
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.
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
Upvotes: 1