I need to calculate some values in a file (Case1.log) which contains,
Fault Classes #faults
(total)
------------------------------------------------------------------------------------- --------------
FU (full) 3186
----------------------------------------------------------------------------------- --------------
DS (det_simulation) 1625 (51.00%)
DI (det_implication) 393 (12.34%)
PU (posdet_untestable) 123 ( 1.32%)
PT (posdet_testable) 420 ( 2.43%)
UU (unused) 210 ( 6.59%)
TI (tied) 52 ( 1.63%)
BL (blocked) 4 ( 0.13%)
RE (redundant) 9 ( 0.28%)
AU (atpg_untestable) 893 (28.03%)
I have extracted the values from the above file using bash scripting as below,
#! /bin/bash
DS=$(grep DS $1 | awk -F " " '{print $3" "}')
echo "DS=$DS"
DI=$(grep DI $1 | awk -F " " '{print $3" "}')
echo "DI=$DI"
UU=$(grep UU $1 | awk -F " " '{print $3" "}')
echo "UU=$UU"
TI=$(grep TI $1 | awk -F " " '{print $3" "}')
echo "TI=$TI"
BL=$(grep BL $1 | awk -F " " '{print $3" "}')
echo "BL=$BL"
RE=$(grep RE $1 | awk -F " " '{print $3" "}')
echo "RE=$RE"
PU=$(grep PU $1 | awk -F " " '{print $3" "}')
echo "PU=$PU"
PT=$(grep PT $1 | awk -F " " '{print $3" "}')
echo "PT=$PT"
FU=$(grep FU $1 | awk -F " " '{print $3" "}')
echo "FU=$FU"
Now I need to use the extracted values to calculate an equation,
NU = expr $DS $DI $PT $PU
DE = expr $FU - $UU - $TI - $BL - $RE | bc -l
Result = expr $NU / $DE \*100
echo $Result
Upon running the script
bash Script.sh Case1.log
$NU, $DE & $ Result are showing an Error text as
DS=1625
DI=393
UU=210
TI=52
BL=4
RE=9
PU=123
PT=420
FU=3186
2561
2911
expr: missing operand
Try 'expr --help' for more information.
/
expr: syntax error: unexpected argument ‘case1.log’
CodePudding user response:
Doing it entirely with awk:
#!/usr/bin/env -S awk -f
# Parse records containing key of two uppercase letters
$1 ~ /[A-Z]{2}/ {
# Populate associative array with captured key and value
a[$1] = $3
# For debug purpose
printf("%s = %s\n", $1, $3)
}
END {
# Now that all values have been captured into the associative array,
# perform computations
NU = a["DS"] a["DI"] a["PT"] a["PU"]
DE = a["FU"] - a["UU"] - a["TI"] - a["BL"] - a["RE"]
result = 100 * NU / DE
printf("\nNU = %d\nDE = %d\n", NU, DE)
printf("100 * NU / DE = %f\n", result)
}
Save awk script above for example as nuderatio
, and
make it executable chmod x nuderatio
and run it
./nuderatio Case1.log
Output it get from your sample Case1.log
:
FU = 3186
DS = 1625
DI = 393
PU = 123
PT = 420
UU = 210
TI = 52
BL = 4
RE = 9
AU = 893
NU = 2561
DE = 2911
100 * NU / DE = 87.976640
And same entirely in Bash:
#!/usr/bin/env bash
declare -A a
while read -r k _ v _ || [[ $k ]]; do
[[ "$k" =~ [A-Z]{2} ]] || continue
a[$k]="$v"
printf '%s = %s\n' "$k" "$v"
done < "$1"
NU=$((a["DS"] a["DI"] a["PT"] a["PU"]))
DE=$((a["FU"] - a["UU"] - a["TI"] - a["BL"] - a["RE"]))
# Precision decimals
p=8
r=$((10**p * 100 * NU / DE))
result="${r:0:$((${#r} - p))}.${r: -$p}"
printf '\nNU = %d\nDE = %d\n' $NU $DE
LC_ALL=C printf '100 * NU / DE = %f\n' "$result"
CodePudding user response:
There are two simple ways to do calculations in UNIX/Linux shells: $((...))
and awk
.
$((...))
is very simple:
Prompt> echo $((1 2*3))
7
However, it only covers integer calculation:
Prompt> echo $((3/5))
0
So, once floating point arithmetic is involved, it's advised to use another system, like awk
:
Prompt> awk '{print 3/5}'
0.6
Oh, as far as percentages are concerned: integer arithmetic has a tiny drawback as you can see (how much percent is 3/5):
Prompt> echo $((100 * 3 / 5))
60
Prompt> echo $((3 / 5 * 100))
0
(first, 3/5 gets calculated, being zero, ...)