我试图在shell脚本中添加两个十六进制数字,并将结果存储为十六进制数字。
let "step_size = 10"
let "start_num = 20000000"
let "size = 64"
for (( i = 0; i < 1000; i = $i + $step_size ))
do
for (( j = 0; j < $step_size; j++ ))
do
let "temp = $(( $(( $i * $step_size)) + $(( $j * $size )) ))"
num=`echo "obase=16; $temp" | bc`
echo $num
num2=`obase=16;ibase=16; echo $start_num \\+ $num | bc`
echo $start_num $num $num2
echo "****"
done
done
并非所有结果都是错误的。我只在$num = C0
输出
0
20000000 0 20000000
****
40
20000000 40 20000040
****
80
20000000 80 20000080
****
C0
20000000 C0 20000090 #This is the error!!
****
100
20000000 100 20000100
****
...
...
...
1C0
20000000 1C0 20000190 #Error again!!
我正在使用zshell。我不确定为什么会这样。任何帮助都非常感谢。
由于
答案 0 :(得分:3)
@konsolebox有一个正确的修复,但我认为OP中显示的行为有点神秘,所以似乎值得解释。
首先,很明显
num2=`obase=16;ibase=16; echo $start_num \\+ $num | bc`
不正确,因为它设置了shell变量obase
和ibase
,而不是将赋值传递给bc
。此外,没有必要引用 + 。但是为什么bc
不会产生 \ 中的错误,就像该行以现代形式编写一样:
num2=$(obase=16;ibase=16; echo $start_num \\+ $num | bc)
答案是`…`
和$(…)
之间存在细微差别:
% `echo echo \\+`
+
% $(echo echo \\+)
\+
引用bash
manual:
当使用旧式反引号形式的替换时,反斜杠保留其字面含义,除非后跟 $ ,`或 \ 。第一个不带反斜杠的反引号会终止命令替换。使用
$(command)
表单时,括号内的所有字符组成命令;没有人受到特别对待。
实际上,这意味着反引用版本会解释\
- 两次转义:首先扫描反引号字符串,\\+
变为\+
,然后第二次解析生成的命令时,\+
变为+
。
第二个问题是“20000090来自哪里?”答案是,bc
解释数字的方式是一个奇怪的特征。值得引用man bc
的完整段落(强调添加):
输入数字可能包含字符
0-9
和A-F
。 (注意:它们必须是大写字母。小写字母是变量名。)单个数字的数字始终具有数字的值,而不管ibase
的值。 (即A = 10
。)对于多位数字,bc
将所有大于或等于ibase
的输入数字更改为ibase-1
的值。这使得数字FFF
始终是输入库的最大3位数。
由于ibase
未设置bc
(见上文),bc
将C0
解释为十进制90
,尽管它会解释为{{1}小数C
。
最后,使用12
或bash
,以下工作正常,无需zsh
:
bc
答案 1 :(得分:1)
可能
num2=`obase=16;ibase=16; echo $start_num \\+ $num | bc`
应该是
num2=`echo "obase=16;ibase=16;$start_num + $num" | bc`
你根本没有计算十六进制。
我还建议像这样简化版本:
#!/bin/zsh
step_size=10
start_num=20000000
size=64
for (( i = 0; i < 1000; i += step_size )); do
for (( j = 0; j < step_size; ++j )); do
(( temp = (i * step_size) + (j * size) ))
num=$(echo "obase=16; $temp" | bc)
echo "$num"
num2=$(echo "obase=16;ibase=16;$start_num + $num" | bc)
echo "$start_num $num $num2"
echo "****"
done
done
它在Zsh和Bash都有效。
# bash temp.zsh | head -20
0
20000000 0 20000000
****
40
20000000 40 20000040
****
80
20000000 80 20000080
****
C0
20000000 C0 200000C0
****
100
20000000 100 20000100
****
140
20000000 140 20000140
****
180
20000000 180 20000180