#!/bin/bash
x=${1//[^0-9]/}
sum=0
for ((i=0; i<${#x}; i++)); do
((sum+=${x:i:1}))
done
echo $sum
我是 Linux 新手。您能一步步向我解释一下这段代码吗?我只是想用粗体向你展示我不明白的那一行。
我这里有答案:
$ ./summ_of_digits 115
7
任务:形成参数的数字和
- 程序名是数字的总和
- 该程序接收一个或多个数字作为参数,并计算每个指定数字的数字之和。
- 输出的每一行都包含数字及其数字总和。
- 例子:
$ digit sum 19 115
19 10
115 7
答案1
x=${1//[^ 0-9]/}
$1
是第一个位置参数/命令行参数。
${var//pattern/replace}
取值$var
并替换所有出现的图案和代替。这里,模式是[^ 0-9]
,表示不是空格或(*)0
之间的任何单个字符。9
这替代品部分为空,因此它们被删除,结果扩展,然后分配给x
.
(* 取决于可能包含非 ASCII 数字的区域设置,这可能无法在稍后的脚本中使用算术运算。)
${#x}
${#var}
是变量中值的长度。
${x:i:1}
${var:position:count}
扩展到数数字符开始于位置根据 的值$var
,${x:i:1}
位置 处的字符也是如此i
。
参见例如3.5.3 Shell参数扩展在 Bash 的手册中。
for ((i=0; i<${#x}; i++))
这是一个算术循环,有点像for
C 中循环的常见形式。参见https://www.gnu.org/software/bash/manual/html_node/Looping-Constructs.html
请注意,字符位置是从零开始索引的,因此在 string 中abc
,c
位于位置 2,这就是循环从零到比字符串长度小 1 的原因。
很容易看出,如果调用脚本,sumscript.sh 123456789
输出是45
.同样对于sumscript.sh 1234x5x6789
.不知道为什么他们会允许这个空间,因为它会在算术中产生错误。
答案2
x=${1//[^0-9]/}
接受给定脚本的第一个参数并删除所有非数字字符:
$ script 123xxx
# `$1` is equal to 123
for ((i=0; i<${#x}; i++)); do
$x
从 0 循环到(3) 的值减去 1 (2)的长度:
# i is equal in the loop to
0
1
2
((sum+=${x:i:1}))
在每个循环中将字符串中给定的sum
字符位置的值相加:x
i
0 + 1 = 1
1 + 2 = 3
3 + 3 = 6
所以最后的结果sum
是6。