【问题标题】:Arithmetic operation on all elements in BASH array对 BASH 数组中所有元素的算术运算
【发布时间】:2015-10-21 11:21:08
【问题描述】:

假设我们有一个包含整数的 BASH 数组:

declare -a arr=( 1 2 3 )

我想对每个元素进行算术运算,例如添加 1. 是否有 for 循环的替代方法:

for (( i=0 ; i<=${#arr[@]}-1 ; i++ )) ; do
    arr[$i]=$(( ${arr[$i]} + 1 ))
done

我尝试了几个选项:

arr=$(( ${arr[@]} + 1 ))

失败,而

arr=$(( $arr + 1 ))

结果

echo ${arr[@]}
2 2 3

因此只有第一个(第零个)元素被更改。

我阅读了有关 awk 解决方案的信息,但想知道 BASH 算法是否支持对每个数组元素进行此类批处理操作。

【问题讨论】:

  • 我认为没有其他选择。附带说明一下,我使用的任何编程语言都不能原生地做到这一点。另外,您可以将arr[$i]=$(( ${arr[$i]} + 1 )) 简化为arr[$i]++
  • 我不知道您的首选语言,但例如FORTRAN 确实支持 arr(:) = arr(:) + 1arr3(:) = arr1(:) * arr2(:) ,所以我希望 BASH 有能力。抱歉,我无法重现 arr[$i]++ 的东西。需要解释一下吗?
  • 忘记了括号。正确的语法是(( $arr[$i]++ ))
  • 如果有函数,shell 只会在后台循环。因此,如果它困扰您,只需编写自己的函数即可。
  • @Plutox 抱歉,仍然无法重现,您能否明确地从头到尾编写 for 循环?提前致谢。

标签: arrays bash arithmetic-expressions


【解决方案1】:

你可以使用 eval 来感受一下 lambda 函数(不确定语法,但这应该是主要思想):

eval "function add1 { x=$1; y=$((x+1)) ; return $y; }"
for (( i=0 ; i<=${#arr[@]}-1 ; i++ )) ; do
    add1 ${arr[i]}
done

【讨论】:

  • 我认为这不能回答问题。 OP 希望完全避免 for 循环
  • eval 的使用也是毫无意义的,因为参数扩展将在函数定义之前进行扩展。 return 用于返回退出状态,而不是计算。
【解决方案2】:

我知道您的问题并不新鲜,但您可以通过将数组声明为 integer 然后应用替换来完成您想要的:

declare -ia arr=( 1 2 3 )
value=1

declare -ia 'arr_added=( "${arr[@]/%/+$value}" )'
echo "arr_added: ${arr_added[*]}"

value=42
declare -ia 'arr_added=( "${arr[@]/%/+$value}" )'
echo "arr_added: ${arr_added[*]}"

它输出:

arr_added: 2 3 4
arr_added: 43 44 45

您也可以执行其他数学运算:

value=3
declare -ia 'arr_multd=( "${arr[@]/%/*$value}" )'
echo "arr_multd: ${arr_multd[*]}"

输出:

arr_multd: 3 6 9

【讨论】:

  • 谢谢 - 在我的测试中也可以不使用引号,例如 declare -ia new_arr=( ${arr[@]}/%/+$value }。有没有这方面的文件?我在man bash 中没有看到它。
  • 是的,在数组文档中没有直接提及-i,无论是在任何手册页还是 TLDP 等中。您可以检查-i,尽管在“键入变量:声明或排版”[tldp.org/LDP/abs/html/declareref.html]。它适用于任何变量,包括数组。
猜你喜欢
  • 2015-06-02
  • 2012-06-19
  • 2012-02-26
  • 1970-01-01
  • 2020-07-16
  • 1970-01-01
  • 2014-12-24
  • 2019-08-17
  • 2018-12-30
相关资源
最近更新 更多