有什么方法可以自定义 bc 计算器中变量的初始化吗?

有什么方法可以自定义 bc 计算器中变量的初始化吗?

bc 计算器似乎为未初始化的变量分配零值。我想改变这种行为,以便当 bc 遇到未初始化的变量时,它会将表达式标记为无效。例如,在下面的代码中,

echo "foo + bar" | bc -l

bc 将值 0 赋给 foo 和 bar 并返回“0”。我希望它返回空字符串“”或以其他方式指示“foo + bar”是无效表达式。有没有办法在 bc 中实现这一目标?

答案1

为了回答我自己的问题,除了在 bc 中将未声明的变量标记为无效的方法之外,我想出了一个可行的解决方案,以防它对其他人有用。 bc 要执行的表达式首先通过 sed 命令进行管道传输,该命令会从表达式中删除任何保留的 bc 字。任何剩余的变量名都被认为是未声明的变量,并且整个表达式被转换为一个语句,该语句在 bc 中执行时将强制出现错误(我选择了“1/0”,但是可以构造许多替代错误标志中的任何一个) .)

生成运行时“除以零”错误:

echo 'foo + bar' | sed -E '
    ## Save the original expression in the hold space
    h
    ## Recursively replace all bc reserved words with a unique token string (¦§§¦)
    :again
    s/auto|break|continue|define|else|for|halt|ibase|if|last|length|limits|obase|print|quit|read|return|scale|sqrt|warranty|while/¦§§¦/g
    s/(a|c|e|j|l|s)([(][^)]*[)])/¦§§¦\2/g
    t again
    ## If the expression contains any bc reserved words abutting one another, mark the expression as invalid, and skip to the end of the sed script
    /¦§§¦¦§§¦/s/^.+$/1\/0/
    t
    ## Replace all tokens with spaces
    s/¦§§¦/ /g
    ## If any variable names remain, treat them as undeclared variables, mark the expression as invalid, and skip to the end of the sed script
    ## Prior to doing this, reset the t command so that it can recognize if a substitution takes place in the s command
    t reset
    :reset
    /[a-z][a-z0-9_]*/s/^.+$/1\/0/
    t
    ## If the expression does not have undeclared variable names, get the original expression from the hold space
    g
' | bc -l

返回正确答案 = 246:

echo '123 + 123' | sed -E '
    ## Save the original expression in the hold space
    h
    ## Recursively replace all bc reserved words with a unique token string (¦§§¦)
    :again
    s/auto|break|continue|define|else|for|halt|ibase|if|last|length|limits|obase|print|quit|read|return|scale|sqrt|warranty|while/¦§§¦/g
    s/(a|c|e|j|l|s)([(][^)]*[)])/¦§§¦\2/g
    t again
    ## If the expression contains any bc reserved words abutting one another, mark the expression as invalid, and skip to the end of the sed script
    /¦§§¦¦§§¦/s/^.+$/1\/0/
    t
    ## Replace all tokens with spaces
    s/¦§§¦/ /g
    ## If any variable names remain, treat them as undeclared variables, mark the expression as invalid, and skip to the end of the sed script
    ## Prior to doing this, reset the t command so that it can recognize if a substitution takes place in the s command
    t reset
    :reset
    /[a-z][a-z0-9_]*/s/^.+$/1\/0/
    t
    ## If the expression does not have undeclared variable names, get the original expression from the hold space
    g
' | bc -l

编辑说明:这是我原始提交的改进,在检测未声明的变量名称方面更加准确。

答案2

考虑使用expr?

$ expr foo + bar
expr: non-integer argument
$ expr 1 + 5
6

相关内容