与ksh相反,它允许多维数组,bash(4.2或更低版本)不允许多维数组。 我通过在元素中使用分隔符来解决这个问题,然后第一个数组的每个元素都可以自己制作成数组。 敌人的例子:
GPIO=("in:down:0:22:1-1.4:17:usb:usb port 3 mgmt button"
"in:down:0:13:1-1.5:18:usb:usb port 4 mgmt button")
然后访问第一行的第三个元素我会做这样的事情:
eval $(echo "ROW0=($(echo "${GPIO[0]}" | awk -F: '{ for(i=1;i<=NF;i++) printf("\"%s\" ",$i);}' ))")
echo ${ROW0[2]}
我不喜欢这样做,但我没有找到解决问题的更简洁方法。 是否有一个更整洁,更有效的解决问题的方法,同时仍然像阵列一样接近它?
还有一种解决方法,使用关联数组并在元素索引中添加假的第二个索引:
declare -A FAKE2DIMARRAY
FAKE2DIMARRAY=(
[0,0]="first row first element"
[0,1]="first row second element"
[1,0]="second row first element"
[1,1]="second row second element"
)
虽然这个解决方案非常简洁有效,但如果它有很多行和元素,它会使数组的定义变得混乱。 例如,我的完整GPIO阵列实际上是16x8,这需要128行并注意正确索引每一行...在这种情况下,这也不是最优的。
答案 0 :(得分:2)
自动创建(假的)多维fullarray
并不困难。要从数组中提取索引:请查看结尾。
现在使用字符串创建多个数组:
IFS=: read -a arr0 <<<"in:down:0:22:1-1.4:17:usb:usb port 3 mgmt button"
IFS=: read -a arr1 <<<"in:down:0:13:1-1.5:18:usb:usb port 4 mgmt button"
在这个示例中,只需使用相同名称arr
开头即可。
然后,自动系统将采用名称以arr
开头的所有变量作为行
并且这些数组中的值计数为列:
#!/bin/bash
IFS=: read -a row1 <<<"in:down:0:22:1-1.4:17:usb:usb port 3 mgmt button"
IFS=: read -a row2 <<<"in:down:0:13:1-1.5:18:usb:usb port 4 mgmt button"
#echo "one ${row1[@]}"
#echo "two ${row2[@]}"
declare -A fullarray
# Note that ${!row*} lists all the variables that start with arr.
for hrow in ${!row*}; do
#echo "row $hrow"
for (( column=0; column<${#row1[@]}; column++ )); do
#echo "column $column"
indirect=$hrow[$column]
#echo "indirect $indirect ${!indirect}"
fullarray[${hrow#row},$column]=${!indirect}
done
done
declare -p "fullarray"
取消注释回显以查看数组是如何构建的。
从declare -p fullarray
的输出中可以看出,变量具有数组中的所有值(hrow,column),如果行和列是来自的数字,则可以使用fullarray[$hrow,$column]
访问每个值0及以上。
在这种情况下,将$
保留在变量中,因为我们需要索引的字符串表示(而不是它们的数字等价物)。
当然,我想对每行数组的赋值已经解决了你的问题而无需使用awk。
这仅取决于使用:
indirect=arr$row[$column]
${!indirect}
对你来说已经足够了。 : - )
要从完整数组中提取索引,如果需要,可以分三步完成。首先从fullarray获取所有索引:
allind=(${!fullarray})
而且,由于allind本身就是一个数组,你可以使用逗号作为分隔符来提取每个部分:
rowind=( ${allind[@]//,*} )
由于rowind将包含所有列的所有行索引,因此将重复这些值。只需排序并删除重复:
rowind=( $(printf '%s\n' "${rowind[@]}"|sort -u) )
并且,如果需要,请查看行索引的定义:
declare -p rowind
列的相同过程(除了已定义allind):
allind=(${!fullarray[@]})
columnind=( ${allind[@]//*,} )
columnind=( $(printf '%s\n' "${columnind[@]}"|sort -u) )
declare -p columnind