Bash For循环中如何比较$@参数数组不同索引位置的元素?
Bash位置参数相邻元素比较问题解决方案
报错原因
Bash内置的位置参数数组$@不属于普通索引数组,不支持${@[索引]}的下标取值语法,这是你遇到bad substitution报错的直接原因。
可行方案
推荐优先选择第一种方案,可读性更高、不易出错。
方案1:将位置参数转存为普通数组
先把$@的内容赋值给自定义的普通数组,再用下标遍历即可:
#!/bin/bash # 转存位置参数到普通数组,保留参数原有空格等特殊格式 args=("$@") # 循环边界减1,避免i+1超出数组长度导致越界 for (( i = 0; i < ${#args[@]} - 1; i++ )); do # 如果你要比较的是字符串而非数值,请把判断条件替换为: # if [[ "${args[i]}" < "${args[i+1]}" ]] if (( args[i] < args[i+1] )); then echo "true" fi done
方案2:用间接变量直接访问位置参数
Bash的位置参数从1开始计数,你可以通过${!n}的间接取值语法直接读取第n个位置参数,无需转存数组:
#!/bin/bash # 位置参数从1开始计数,循环到总个数减1即可避免越界 for (( i = 1; i < $#; i++ )); do next_idx=$((i + 1)) # 字符串比较同理替换判断条件即可 if (( ${!i} < ${!next_idx} )); then echo "true" fi done
原代码额外问题修正
你原本的循环条件写的是i < ${#@},会导致最后一次循环时i+1对应的位置参数不存在,即使解决了下标访问的问题也会出现越界报错,两种方案都已经修正了这个边界问题。
内容的提问来源于stack exchange,提问作者Kusku
相关产品推荐
相关产品推荐

