awk浮点表示法

时间:2014-03-26 15:38:40

标签: bash shell awk

嘿我是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)

3 个答案:

答案 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)

您可以使用echoawk执行此操作。

#!/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。