我想知道如何在bash中声明一个2D数组然后初始化为0.
在C中它看起来像这样:
int a[4][5] = {0};
Run Code Online (Sandbox Code Playgroud)
我如何为元素赋值?如在C:
a[2][3] = 3;
Run Code Online (Sandbox Code Playgroud)
jm6*_*666 62
您可以使用哈希模拟它们,但需要关注前导零和许多其他事情.下一个演示工作,但它远非最佳解决方案.
#!/bin/bash
declare -A matrix
num_rows=4
num_columns=5
for ((i=1;i<=num_rows;i++)) do
for ((j=1;j<=num_columns;j++)) do
matrix[$i,$j]=$RANDOM
done
done
f1="%$((${#num_rows}+1))s"
f2=" %9s"
printf "$f1" ''
for ((i=1;i<=num_rows;i++)) do
printf "$f2" $i
done
echo
for ((j=1;j<=num_columns;j++)) do
printf "$f1" $j
for ((i=1;i<=num_rows;i++)) do
printf "$f2" ${matrix[$i,$j]}
done
echo
done
Run Code Online (Sandbox Code Playgroud)
上面的例子创建了一个带有随机数的4x5矩阵,并将其打印出来,并带有示例结果
1 2 3 4
1 18006 31193 16110 23297
2 26229 19869 1140 19837
3 8192 2181 25512 2318
4 3269 25516 18701 7977
5 31775 17358 4468 30345
Run Code Online (Sandbox Code Playgroud)
原则是:创建一个关联数组,其中索引是一个字符串3,4
.好处:
30,40,2
3维.${matrix[2,3]}
Sir*_*hos 23
Bash不支持多维数组.
您可以使用间接扩展来模拟它:
#!/bin/bash
declare -a a0=(1 2 3 4)
declare -a a1=(5 6 7 8)
var="a1[1]"
echo ${!var} # outputs 6
Run Code Online (Sandbox Code Playgroud)
使用此方法也可以进行分配:
let $var=55
echo ${a1[1]} # outputs 55
Run Code Online (Sandbox Code Playgroud)
编辑1:要从文件中读取此类数组,行中的每一行以及由空格分隔的值,请使用以下命令:
idx=0
while read -a a$idx; do
let idx++;
done </tmp/some_file
Run Code Online (Sandbox Code Playgroud)
编辑2:要声明并初始化a0..a3[0..4]
为0
,您可以运行:
for i in {0..3}; do
eval "declare -a a$i=( $(for j in {0..4}; do echo 0; done) )"
done
Run Code Online (Sandbox Code Playgroud)
Jah*_*hid 22
Bash没有多维数组.但您可以使用关联数组模拟一些类似的效果.以下是假装用作多维数组的关联数组的示例:
declare -A arr
arr[0,0]=0
arr[0,1]=1
arr[1,0]=2
arr[1,1]=3
echo "${arr[0,0]} ${arr[0,1]}" # will print 0 1
Run Code Online (Sandbox Code Playgroud)
如果未将数组声明为关联(with -A
),则上述操作无效.例如,如果省略该declare -A arr
行,echo
则将打印2 3
而不是0 1
,因为0,0
,1,0
这将被视为算术表达式并计算为0
(逗号运算符右侧的值).
2D 数组可以在 bash 中通过声明 1D 数组来实现,然后可以使用 访问元素(r * col_size) + c)
。下面的逻辑删除一维数组 ( str_2d_arr
) 并打印为二维数组。
col_size=3
str_2d_arr=()
str_2d_arr+=('abc' '200' 'xyz')
str_2d_arr+=('def' '300' 'ccc')
str_2d_arr+=('aaa' '400' 'ddd')
echo "Print 2D array"
col_count=0
for elem in ${str_2d_arr[@]}; do
if [ ${col_count} -eq ${col_size} ]; then
echo ""
col_count=0
fi
echo -e "$elem \c"
((col_count++))
done
echo ""
Run Code Online (Sandbox Code Playgroud)
输出是
Print 2D array
abc 200 xyz
def 300 ccc
aaa 400 ddd
Run Code Online (Sandbox Code Playgroud)
下面的逻辑对于从上面声明的一维数组中获取每一行非常有用str_2d_arr
。
# Get nth row and update to 2nd arg
get_row_n()
{
row=$1
local -n a=$2
start_idx=$((row * col_size))
for ((i = 0; i < ${col_size}; i++)); do
idx=$((start_idx + i))
a+=(${str_2d_arr[${idx}]})
done
}
arr=()
get_row_n 0 arr
echo "Row 0"
for e in ${arr[@]}; do
echo -e "$e \c"
done
echo ""
Run Code Online (Sandbox Code Playgroud)
输出是
Row 0
abc 200 xyz
Run Code Online (Sandbox Code Playgroud)
您也可以以更智能的方式解决这个问题
q=()
q+=( 1-2 )
q+=( a-b )
for set in ${q[@]};
do
echo ${set%%-*}
echo ${set##*-}
done
Run Code Online (Sandbox Code Playgroud)
当然,22线解决方案或间接可能是更好的方法,为什么不在每个地方撒上eval.
另一种方法是您可以将每一行表示为字符串,即将2D数组映射到1D数组。然后,您需要做的就是在进行编辑时解包并重新打包行的字符串:
# Init a 4x5 matrix
a=("0 0 0 0 0" "0 0 0 0 0" "0 0 0 0 0" "0 0 0 0 0")
aset() {
row=$1
col=$2
value=$3
IFS=' ' read -r -a tmp <<< "${a[$row]}"
tmp[$col]=$value
a[$row]="${tmp[@]}"
}
# Set a[2][3] = 3
aset 2 3 3
# Show result
for r in "${a[@]}"; do
echo $r
done
Run Code Online (Sandbox Code Playgroud)
输出:
0 0 0 0 0
0 0 0 0 0
0 0 0 3 0
0 0 0 0 0
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
175487 次 |
最近记录: |