Home > Back-end >  How do I calculate values extracted from a file using grep and use those value to calculate
How do I calculate values extracted from a file using grep and use those value to calculate

Time:09-16

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, ...)

  • Related