我在 shell 脚本中编写了三个 hive 查询,用于计算借方、贷方和目标金额,输出以下值:
debit_amount : BOI 4760545.650000 AXIS 284.49000000 SBI 87.220000000 ICICI 14199.66000
credit_amount : BOI 3424.65 AXIS 43.4546 SBI 4.54546 ICICI 3423.3465
target_amount : BOI 4757121.000000 AXIS 241.0354 SBI 82.67454 ICICI 10776.3135
现在我想计算每家银行的借记贷记金额并与 target_amount 值进行比较
在shell脚本中如何写?
我尝试使用 awk 命令但没有得到所需的输出。
答案1
在 Perl 中很容易:
echo "$output" | perl -lane '
$amount{$F[$_]}{$F[0]} = $F[$_ + 1] for 2, 4, 6, 8
}{
for $bank (grep $_, keys %amount) {
print $bank, "\t",
$amount{$bank}{debit_amount} - $amount{$bank}{credit_amount} - $amount{$bank}{target_amount}
}
'
-n
逐行读取输入-a
将每行按空格拆分到@F
数组中-l
添加换行符print
大多数 shell 不支持浮点运算,因此使用外部工具是不可避免的。以下是bash
使用bc
for 进行计算的示例:
amounts=($output)
for bank_idx in 2 4 6 8 ; do
printf '%s\t' ${amounts[bank_idx]}
bc -l <<< "${amounts[bank_idx + 1]} - ${amounts[bank_idx + 11]} - ${amounts[bank_idx + 21]}"
done
${amounts[@]}
是由整个输入构成的数组。对于每个银行(索引 2、4、6 和 8),借方存储在索引 + 1 处,贷方存储在索引 + 11 处,目标存储在索引 + 21 处。
答案2
awk 解决方案,awk 文件
/debit_amount/ { for(i=3;i<=NF;i+=2) { bank[$i]=1 ; debit[$i]=$(i+1) ; } }
/credit_amount/ { for(i=3;i<=NF;i+=2) { bank[$i]=1 ; credit[$i]=$(i+1) ; } }
/target_amount/ { for(i=3;i<=NF;i+=2) { bank[$i]=1 ; target[$i]=$(i+1) ; } }
END {
for ( b in bank ) printf "%-10s: d %f c %f t %f (%f) : %f\n",
b,debit[b],credit[b],credit[b]-debit[b],target[b],target[b]+credit[b]-debit[b] ;
}
作为运行
awk -f test.awk u
并给予
BOI : d 4760545.650000 c 3424.650000 t -4757121.000000 (4757121.000000) : 0.000000
AXIS : d 284.490000 c 43.454600 t -241.035400 (241.035400) : 0.000000
ICICI : d 14199.660000 c 3423.346500 t -10776.313500 (10776.313500) : 0.000000
SBI : d 87.220000 c 4.545460 t -82.674540 (82.674540) : 0.000000
您可以在 printf 语句中调整打印字段。