I have some output from a script thescript
which reads:
202 1 0 1 0 0 0
Now I want to selectively sum this number with awk
, depending on the value of a ${SUM_MASK}
:
SUM_MASK=1,1,0,0,0,0,0
I would like to have something like:
thescript | awk <SOMETHING>
where the each number output of thescript
gets multiplied by the corresponding number in ${SUM_MASK}
, obtaining:
203
as result of: 203 = 202 * 1 + 1 * 1 + 0 * 0 + 1 * 0 + 0 * 0 + 0 * 0 + 0 * 0
This would be similar to the sumproduct
function in spreadsheet software.
The following code snipets do the trick, but I would like to avoid using process substitution:
SUM_MASK="1,1,0,0,0,0,0"; paste <(thescript) <(echo ${SUM_MASK} | tr ',' '\n') | awk '{ SUM += $1 * $2 } END { print SUM }'
and named pipes:
SUM_MASK="1,1,0,0,0,0,0"; mkfifo fA; mkfifo fB; thescript > fA & echo ${SUM_MASK} | tr ',' '\n' > fB & paste fA fB | awk '{ SUM += $1 * $2 } END { print SUM }' > result.text; rm -f fA fB
how could I achieve that?
echo "202 1 0 1 0 0 0" |
awk -v summask="1,1,0,0,0,0,0" '
BEGIN {split(summask, mask, /,/)}
{ sumproduct=0
for (i=1; i<=NF; i++) {
sumproduct += $i * mask[i]
}
print sumproduct
}
'
203
There's no need for external tools such as awk
here -- bash is capable of resolving this with built-in capabilities only. Consider the below implementation as a function:
sumproduct() {
local -a sum_inputs sum_mask
local idx result
# read your sum_inputs into an array from stdin
IFS=', ' read -r -a sum_inputs # this could be <<<"$1" to use the first argument
# and your sum_mask from the like-named variable
IFS=', ' read -r -a sum_mask <<<"$SUM_MASK" # or <<<"$2" for the second argument
# ...iterate over array elements in sum_inputs; find the corresponding sum_mask; math.
result=0
for idx in "${!sum_inputs[@]}"; do
(( result += ${sum_mask[$idx]} * ${sum_inputs[$idx]} ))
done
echo "$result"
}
To test this:
echo "202 1 0 1 0 0 0" | SUM_MASK=1,1,0,0,0,0,0 sumproduct
...correctly yields:
203
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With