嘿我是shell脚本的新手,我正在尝试写一些涉及浮点计算的东西。我打算使用bc或awk。
但是,由于我找不到正确告诉bc do x ^(1/3)的方法,我最终得到了awk。除了一个问题之外我完成了所有工作:为了与awk进行除法,每当我的被除数小于1时,比如说0.0064,awk似乎把它读成0.因此我得到inf作为结果。我不确定我在哪里做错了。
这是我的代码,我需要将计算出的值存储到变量中,而不是将它们打印出来。
我也很好奇bc,awk或简单表达的价值如何处理''形成?它们是作为数值还是字符串读取/存储?
另外,只是使用awk作为计算,我可以做x = $(echo"表达式" | awk)或类似的东西,而不使用awk' {}&中的print表达式#39;
#!/bin/bash
# molar concentration = 0.1 mM per nm^3
MOLAR=0.0001
NA=6.02*10^23
CONV=1*10^24
number_concentration=$(echo "scale=10;$MOLAR * $NA / ($CONV)" | bc)
echo $number_concentration
# determine box size
volume=$(awk 'BEGIN {print 1+$number_concentration}' /dev/null)
echo $volume
# length
a=$(echo awk 'BEGIN {$volume^(1/3)}' /dev/null)
答案 0 :(得分:3)
我这样写,只需要一次调用awk:
MOLAR="0.0001"
NA="6.02*10^23"
CONV="1*10^24"
read concentration volume length < <(
awk "BEGIN {
molar=$MOLAR; na=$NA; conv=$CONV
conc = molar * na / conv
vol = 1 + conc
len = vol ^ (1/3)
printf \"%.8f %.8f %.8f\\n\", conc, vol, len
}"
)
printf "%s\n" $concentration $volume $length
0.00006020
1.00006020
1.00002007
请注意,您可能会遇到浮点数精度损失的问题:
% awk "BEGIN {print $MOLAR, $NA, $CONV}"
0.0001 601999999999999928696832 999999999999999983222784
如果bash变量可以用&#34;科学记数法表示,那么我们就可以了:
MOLAR="0.0001"
NA="6.02e23"
CONV="1e24"
awk -v molar="$MOLAR" -v na="$NA" -v conv="$CONV" 'BEGIN {
conc = molar * na / conv
vol = 1 + conc
len = vol ^ (1/3)
printf "%.8f %.8f %.8f\n", conc, vol, len
}'
答案 1 :(得分:1)
您可以使用echo
和awk
执行此操作。
#!/bin/bash
# molar concentration = 0.1 mM per nm^3
MOLAR=0.0001
NA=6.02*10^23
CONV=1*10^24
number_concentration=$(echo "$MOLAR $NA $CONV" | awk '{print $1*$2/$3}')
echo $number_concentration
# determine box size
volume=$(echo "$number_concentration" | awk '{print 1+$1}')
echo $volume
# length
a=$(echo $volume | awk '{print $1^(1/3)}')
echo $a
答案 2 :(得分:1)
难道你不能在awk中全部完成吗?
awk 'BEGIN {
molar = 0.0001
na = 6.02 * 10 ^ 23
conv = 1 * 10 ^ 24
number_concentration = molar * na / conv
volume = 1 + number_concentration
a = volume ^ (1/3)
print number_concentration, volume, a
}'
6.02e-05 1.00006 1.00002
如果您需要不同的输出格式,请使用printf
代替print
。
如果由于某种原因需要在awk脚本之前在shell中定义变量:
MOLAR="0.0001"
NA="6.02*10^23"
CONV="1*10^24"
awk 'BEGIN {
molar = '"$MOLAR"'
na = '"$NA"'
conv = '"$CONV"'
number_concentration = molar * na / conv
volume = 1 + number_concentration
a = volume ^ (1/3)
print number_concentration, volume, a
}'
6.02e-05 1.00006 1.00002
或甚至不使用awk变量作为初始值:
MOLAR="0.0001"
NA="6.02*10^23"
CONV="1*10^24"
awk 'BEGIN {
number_concentration = ('"$MOLAR"') * ('"$NA"') / ('"$CONV"')
volume = 1 + number_concentration
a = volume ^ (1/3)
print number_concentration, volume, a
}'
6.02e-05 1.00006 1.00002
请注意,以上不是在awk脚本中访问shell变量值的常规方法,通常你会使用awk -v awkvar="$shellvar" ...
传递它们的值,但在这种情况下我们需要实际的文本扩展shell变量在被awk解释之前在awk脚本中在线发生,而通常由于shell变量可能扩展为导致awk语法错误或其他不良行为的东西而导致潜在破坏的行为。
因此,只对数字执行此操作(数字表达式可能是唯一用途):
awk 'BEGIN{awkvar='"$shellvar"'} {script}'
或者这是一个字符串(不确定这实际上是否必要):
awk 'BEGIN{awkvar="'"$shellvar"'"} {script}'
优先于此:
awk -v awkvar="$shellvar" '{script}'
当你完全控制shellvar的内容时,要知道你正在处理的警告,并在awk解释脚本之前就地扩展NEED shellvar。