如何在bash中声明2D数组?

时间:2022-05-27 20:58:11

I'm wondering how to declare a 2D array in bash and then initialize to 0.

我想知道如何在bash中声明一个2D数组,然后初始化为0。

In C it looks like this:

在C中是这样的

int a[4][5] = {0};

And how do I assign a value to an element? As in C:

如何为元素赋值?在C:

a[2][3] = 3;

9 个解决方案

#1


52  

You can simulate them for example with hashes, but need care about the leading zeroes and many other things. The next demonstration works, but it is far from optimal solution.

你可以用散列来模拟它们,但是需要关心前面的零和其他很多东西。下一个演示是可行的,但它远不是最理想的解决方案。

#!/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

the above example creates a 4x5 matrix with random numbers and print it transposed, with the example result

上面的例子创建了一个带有随机数的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

The principle is: Creating one associative array where the index is an string like 3,4. The benefits:

原理是:创建一个关联数组,其中索引是一个字符串,如3、4。的好处:

  • it's possible to use for any-dimension arrays ;) like: 30,40,2 for 3 dimensional.
  • 它可以用于任何尺寸的数组;)例如:30、40、2的三维空间。
  • the syntax is close to "C" like arrays ${matrix[2,3]}
  • 语法接近于“C”,如数组${矩阵[2,3]}

#2


22  

Bash does not support multidimensional arrays.

Bash不支持多维数组。

You can simulate it though by using indirect expansion:

你可以通过间接扩展来模拟它:

#!/bin/bash
declare -a a0=(1 2 3 4)
declare -a a1=(5 6 7 8)
var="a1[1]"
echo ${!var}  # outputs 6

Assignments are also possible with this method:

这种方法也可以分配任务:

let $var=55
echo ${a1[1]}  # outputs 55

Edit 1: To read such an array from a file, with each row on a line, and values delimited by space, use this:

编辑1:从一个文件中读取这样一个数组,每一行在一行上,并且在空间上分隔的值,使用这个:

idx=0
while read -a a$idx; do
    let idx++;
done </tmp/some_file

Edit 2: To declare and initialize a0..a3[0..4] to 0, you could run:

编辑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

#3


18  

Bash doesn't have multi-dimensional array. But you can simulate a somewhat similar effect with associative arrays. The following is an example of associative array pretending to be used as multi-dimensional array:

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

If you don't declare the array as associative (with -A), the above won't work. For example, if you omit the declare -A arr line, the echo will print 2 3 instead of 0 1, because 0,0, 1,0 and such will be taken as arithmetic expression and evaluated to 0 (the value to the right of the comma operator).

如果您没有将数组声明为关联(与-A),则上述方法将不起作用。例如,如果您省略了声明- - - arr行,那么echo将输出2 3而不是0 1,因为0、0、1、0等将被作为算术表达式计算并赋值为0(逗号操作符右边的值)。

#4


4  

Another approach is you can represent each row as a string, i.e. mapping the 2D array into an 1D array. Then, all you need to do is unpack and repack the row's string whenever you make an edit:

另一种方法是,您可以将每一行表示为字符串,即将2D数组映射为一维数组。然后,当您进行编辑时,您需要做的就是打开并重新打包行的字符串:

# 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")

function aset {
    IFS=' ' read -r -a tmp <<< "${a[$1]}"
    tmp[$2]=$3
    a[$1]="${tmp[@]}"
}

# Set a[2][3] = 3
aset 2 3 3

# Show result
for r in "${a[@]}"; do
  echo $r
done

Outputs:

输出:

0 0 0 0 0
0 0 0 0 0
0 0 0 3 0
0 0 0 0 0

#5


3  

You can also approach this in a much less smarter fashion

你也可以用一种不那么聪明的方式来处理这个问题。

q=()
q+=( 1-2 )
q+=( a-b )

for set in ${q[@]};
do
echo ${set%%-*}
echo ${set##*-}
done

of course a 22 line solution or indirection is probably the better way to go and why not sprinkle eval every where to .

当然,一个22线的解决方案或间接的方法可能是更好的方法,为什么不把eval的每一处都撒上。

#6


3  

A way to simulate arrays in bash (it can be adapted for any number of dimensions of an array):

一种在bash中模拟数组的方法(它可以适用于数组的任意多个维度):

#!/bin/bash

## The following functions implement vectors (arrays) operations in bash:
## Definition of a vector <v>:
##      v_0 - variable that stores the number of elements of the vector
##      v_1..v_n, where n=v_0 - variables that store the values of the vector elements

VectorAddElementNext () {
# Vector Add Element Next
# Adds the string contained in variable $2 in the next element position (vector length + 1) in vector $1

    local elem_value
    local vector_length
    local elem_name

    eval elem_value=\"\$$2\"
    eval vector_length=\$$1\_0
    if [ -z "$vector_length" ]; then
        vector_length=$((0))
    fi

    vector_length=$(( vector_length + 1 ))
    elem_name=$1_$vector_length

    eval $elem_name=\"\$elem_value\"
    eval $1_0=$vector_length
}

VectorAddElementDVNext () {
# Vector Add Element Direct Value Next
# Adds the string $2 in the next element position (vector length + 1) in vector $1

    local elem_value
    local vector_length
    local elem_name

    eval elem_value="$2"
    eval vector_length=\$$1\_0
    if [ -z "$vector_length" ]; then
        vector_length=$((0))
    fi

    vector_length=$(( vector_length + 1 ))
    elem_name=$1_$vector_length

    eval $elem_name=\"\$elem_value\"
    eval $1_0=$vector_length
}

VectorAddElement () {
# Vector Add Element
# Adds the string contained in the variable $3 in the position contained in $2 (variable or direct value) in the vector $1

    local elem_value
    local elem_position
    local vector_length
    local elem_name

    eval elem_value=\"\$$3\"
    elem_position=$(($2))
    eval vector_length=\$$1\_0
    if [ -z "$vector_length" ]; then
        vector_length=$((0))
    fi

    if [ $elem_position -ge $vector_length ]; then
        vector_length=$elem_position
    fi

    elem_name=$1_$elem_position

    eval $elem_name=\"\$elem_value\"
    if [ ! $elem_position -eq 0 ]; then
        eval $1_0=$vector_length
    fi
}

VectorAddElementDV () {
# Vector Add Element
# Adds the string $3 in the position $2 (variable or direct value) in the vector $1

    local elem_value
    local elem_position
    local vector_length
    local elem_name

    eval elem_value="$3"
    elem_position=$(($2))
    eval vector_length=\$$1\_0
    if [ -z "$vector_length" ]; then
        vector_length=$((0))
    fi

    if [ $elem_position -ge $vector_length ]; then
        vector_length=$elem_position
    fi

    elem_name=$1_$elem_position

    eval $elem_name=\"\$elem_value\"
    if [ ! $elem_position -eq 0 ]; then
        eval $1_0=$vector_length
    fi
}

VectorPrint () {
# Vector Print
# Prints all the elements names and values of the vector $1 on sepparate lines

    local vector_length

    vector_length=$(($1_0))
    if [ "$vector_length" = "0" ]; then
        echo "Vector \"$1\" is empty!"
    else
        echo "Vector \"$1\":"
        for ((i=1; i<=$vector_length; i++)); do
            eval echo \"[$i]: \\\"\$$1\_$i\\\"\"
            ###OR: eval printf \'\%s\\\n\' \"[\$i]: \\\"\$$1\_$i\\\"\"
        done
    fi
}

VectorDestroy () {
# Vector Destroy
# Empties all the elements values of the vector $1

    local vector_length

    vector_length=$(($1_0))
    if [ ! "$vector_length" = "0" ]; then
        for ((i=1; i<=$vector_length; i++)); do
            unset $1_$i
        done
        unset $1_0
    fi
}

##################
### MAIN START ###
##################

## Setting vector 'params' with all the parameters received by the script:
for ((i=1; i<=$#; i++)); do
    eval param="\${$i}"
    VectorAddElementNext params param
done

# Printing the vector 'params':
VectorPrint params

read temp

## Setting vector 'params2' with the elements of the vector 'params' in reversed order:
if [ -n "$params_0" ]; then
    for ((i=1; i<=$params_0; i++)); do
        count=$((params_0-i+1))
        VectorAddElement params2 count params_$i
    done
fi

# Printing the vector 'params2':
VectorPrint params2

read temp

## Getting the values of 'params2'`s elements and printing them:
if [ -n "$params2_0" ]; then
    echo "Printing the elements of the vector 'params2':"
    for ((i=1; i<=$params2_0; i++)); do
        eval current_elem_value=\"\$params2\_$i\"
        echo "params2_$i=\"$current_elem_value\""
    done
else
    echo "Vector 'params2' is empty!"
fi

read temp

## Creating a two dimensional array ('a'):
for ((i=1; i<=10; i++)); do
    VectorAddElement a 0 i
    for ((j=1; j<=8; j++)); do
        value=$(( 8 * ( i - 1 ) + j ))
        VectorAddElementDV a_$i $j $value
    done
done

## Manually printing the two dimensional array ('a'):
echo "Printing the two-dimensional array 'a':"
if [ -n "$a_0" ]; then
    for ((i=1; i<=$a_0; i++)); do
        eval current_vector_lenght=\$a\_$i\_0
        if [ -n "$current_vector_lenght" ]; then
            for ((j=1; j<=$current_vector_lenght; j++)); do
                eval value=\"\$a\_$i\_$j\"
                printf "$value "
            done
        fi
        printf "\n"
    done
fi

################
### MAIN END ###
################

#7


1  

One can simply define two functions to write ($4 is the assigned value) and read a matrix with arbitrary name ($1) and indexes ($2 and $3) exploiting eval and indirect referencing.

可以简单地定义两个函数来写($4是赋值的值),并读取一个带有任意名称的矩阵($1)和索引($2和$3),利用eval和间接引用。

#!/bin/bash

matrix_write () {
 eval $1"_"$2"_"$3=$4
 # aux=$1"_"$2"_"$3          # Alternative way
 # let $aux=$4               # ---
}

matrix_read () {
 aux=$1"_"$2"_"$3
 echo ${!aux}
}

for ((i=1;i<10;i=i+1)); do
 for ((j=1;j<10;j=j+1)); do 
  matrix_write a $i $j $[$i*10+$j]
 done
done

for ((i=1;i<10;i=i+1)); do
 for ((j=1;j<10;j=j+1)); do 
  echo "a_"$i"_"$j"="$(matrix_read a $i $j)
 done
done

#8


1  

If each row of the matrix is the same size, then you can simply use a linear array and multiplication.

如果矩阵的每一行都是相同的大小,那么你可以简单地使用一个线性数组和乘法。

That is,

也就是说,

a=()
for (( i=0; i<4; ++i )); do
  for (( j=0; j<5; ++j )); do
     a[i*5+j]=0
  done
done

Then your a[2][3] = 3 becomes

然后a[2][3] = 3就变成了。

a[2*5+3] = 3

This approach might be worth turning into a set of functions, but since you can't pass arrays to or return arrays from functions, you would have to use pass-by-name and sometimes eval. So I tend to file multidimensional arrays under "things bash is simply Not Meant To Do".

这种方法可能值得转换为一组函数,但是由于不能将数组从函数中传递或返回数组,因此必须使用passby -name,有时还需要eval。因此,我倾向于在“things bash根本不打算做”的情况下对多维数组进行归档。

#9


0  

For simulating a 2-dimensional array, I first load the first n-elements (the elements of the first column)

为了模拟二维数组,我首先加载第一个n元素(第一列的元素)

local pano_array=()  

i=0

for line in $(grep  "filename" "$file")
do 
  url=$(extract_url_from_xml $line)
  pano_array[i]="$url"
  i=$((i+1))
done

To add the second column, I define the size of the first column and calculate the values in an offset variable

要添加第二列,我定义第一个列的大小,并计算一个偏移量变量中的值。

array_len="${#pano_array[@]}"

i=0

while [[ $i -lt $array_len ]]
do
  url="${pano_array[$i]}"
  offset=$(($array_len+i)) 
  found_file=$(get_file $url)
  pano_array[$offset]=$found_file

  i=$((i+1))
done

#1


52  

You can simulate them for example with hashes, but need care about the leading zeroes and many other things. The next demonstration works, but it is far from optimal solution.

你可以用散列来模拟它们,但是需要关心前面的零和其他很多东西。下一个演示是可行的,但它远不是最理想的解决方案。

#!/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

the above example creates a 4x5 matrix with random numbers and print it transposed, with the example result

上面的例子创建了一个带有随机数的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

The principle is: Creating one associative array where the index is an string like 3,4. The benefits:

原理是:创建一个关联数组,其中索引是一个字符串,如3、4。的好处:

  • it's possible to use for any-dimension arrays ;) like: 30,40,2 for 3 dimensional.
  • 它可以用于任何尺寸的数组;)例如:30、40、2的三维空间。
  • the syntax is close to "C" like arrays ${matrix[2,3]}
  • 语法接近于“C”,如数组${矩阵[2,3]}

#2


22  

Bash does not support multidimensional arrays.

Bash不支持多维数组。

You can simulate it though by using indirect expansion:

你可以通过间接扩展来模拟它:

#!/bin/bash
declare -a a0=(1 2 3 4)
declare -a a1=(5 6 7 8)
var="a1[1]"
echo ${!var}  # outputs 6

Assignments are also possible with this method:

这种方法也可以分配任务:

let $var=55
echo ${a1[1]}  # outputs 55

Edit 1: To read such an array from a file, with each row on a line, and values delimited by space, use this:

编辑1:从一个文件中读取这样一个数组,每一行在一行上,并且在空间上分隔的值,使用这个:

idx=0
while read -a a$idx; do
    let idx++;
done </tmp/some_file

Edit 2: To declare and initialize a0..a3[0..4] to 0, you could run:

编辑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

#3


18  

Bash doesn't have multi-dimensional array. But you can simulate a somewhat similar effect with associative arrays. The following is an example of associative array pretending to be used as multi-dimensional array:

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

If you don't declare the array as associative (with -A), the above won't work. For example, if you omit the declare -A arr line, the echo will print 2 3 instead of 0 1, because 0,0, 1,0 and such will be taken as arithmetic expression and evaluated to 0 (the value to the right of the comma operator).

如果您没有将数组声明为关联(与-A),则上述方法将不起作用。例如,如果您省略了声明- - - arr行,那么echo将输出2 3而不是0 1,因为0、0、1、0等将被作为算术表达式计算并赋值为0(逗号操作符右边的值)。

#4


4  

Another approach is you can represent each row as a string, i.e. mapping the 2D array into an 1D array. Then, all you need to do is unpack and repack the row's string whenever you make an edit:

另一种方法是,您可以将每一行表示为字符串,即将2D数组映射为一维数组。然后,当您进行编辑时,您需要做的就是打开并重新打包行的字符串:

# 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")

function aset {
    IFS=' ' read -r -a tmp <<< "${a[$1]}"
    tmp[$2]=$3
    a[$1]="${tmp[@]}"
}

# Set a[2][3] = 3
aset 2 3 3

# Show result
for r in "${a[@]}"; do
  echo $r
done

Outputs:

输出:

0 0 0 0 0
0 0 0 0 0
0 0 0 3 0
0 0 0 0 0

#5


3  

You can also approach this in a much less smarter fashion

你也可以用一种不那么聪明的方式来处理这个问题。

q=()
q+=( 1-2 )
q+=( a-b )

for set in ${q[@]};
do
echo ${set%%-*}
echo ${set##*-}
done

of course a 22 line solution or indirection is probably the better way to go and why not sprinkle eval every where to .

当然,一个22线的解决方案或间接的方法可能是更好的方法,为什么不把eval的每一处都撒上。

#6


3  

A way to simulate arrays in bash (it can be adapted for any number of dimensions of an array):

一种在bash中模拟数组的方法(它可以适用于数组的任意多个维度):

#!/bin/bash

## The following functions implement vectors (arrays) operations in bash:
## Definition of a vector <v>:
##      v_0 - variable that stores the number of elements of the vector
##      v_1..v_n, where n=v_0 - variables that store the values of the vector elements

VectorAddElementNext () {
# Vector Add Element Next
# Adds the string contained in variable $2 in the next element position (vector length + 1) in vector $1

    local elem_value
    local vector_length
    local elem_name

    eval elem_value=\"\$$2\"
    eval vector_length=\$$1\_0
    if [ -z "$vector_length" ]; then
        vector_length=$((0))
    fi

    vector_length=$(( vector_length + 1 ))
    elem_name=$1_$vector_length

    eval $elem_name=\"\$elem_value\"
    eval $1_0=$vector_length
}

VectorAddElementDVNext () {
# Vector Add Element Direct Value Next
# Adds the string $2 in the next element position (vector length + 1) in vector $1

    local elem_value
    local vector_length
    local elem_name

    eval elem_value="$2"
    eval vector_length=\$$1\_0
    if [ -z "$vector_length" ]; then
        vector_length=$((0))
    fi

    vector_length=$(( vector_length + 1 ))
    elem_name=$1_$vector_length

    eval $elem_name=\"\$elem_value\"
    eval $1_0=$vector_length
}

VectorAddElement () {
# Vector Add Element
# Adds the string contained in the variable $3 in the position contained in $2 (variable or direct value) in the vector $1

    local elem_value
    local elem_position
    local vector_length
    local elem_name

    eval elem_value=\"\$$3\"
    elem_position=$(($2))
    eval vector_length=\$$1\_0
    if [ -z "$vector_length" ]; then
        vector_length=$((0))
    fi

    if [ $elem_position -ge $vector_length ]; then
        vector_length=$elem_position
    fi

    elem_name=$1_$elem_position

    eval $elem_name=\"\$elem_value\"
    if [ ! $elem_position -eq 0 ]; then
        eval $1_0=$vector_length
    fi
}

VectorAddElementDV () {
# Vector Add Element
# Adds the string $3 in the position $2 (variable or direct value) in the vector $1

    local elem_value
    local elem_position
    local vector_length
    local elem_name

    eval elem_value="$3"
    elem_position=$(($2))
    eval vector_length=\$$1\_0
    if [ -z "$vector_length" ]; then
        vector_length=$((0))
    fi

    if [ $elem_position -ge $vector_length ]; then
        vector_length=$elem_position
    fi

    elem_name=$1_$elem_position

    eval $elem_name=\"\$elem_value\"
    if [ ! $elem_position -eq 0 ]; then
        eval $1_0=$vector_length
    fi
}

VectorPrint () {
# Vector Print
# Prints all the elements names and values of the vector $1 on sepparate lines

    local vector_length

    vector_length=$(($1_0))
    if [ "$vector_length" = "0" ]; then
        echo "Vector \"$1\" is empty!"
    else
        echo "Vector \"$1\":"
        for ((i=1; i<=$vector_length; i++)); do
            eval echo \"[$i]: \\\"\$$1\_$i\\\"\"
            ###OR: eval printf \'\%s\\\n\' \"[\$i]: \\\"\$$1\_$i\\\"\"
        done
    fi
}

VectorDestroy () {
# Vector Destroy
# Empties all the elements values of the vector $1

    local vector_length

    vector_length=$(($1_0))
    if [ ! "$vector_length" = "0" ]; then
        for ((i=1; i<=$vector_length; i++)); do
            unset $1_$i
        done
        unset $1_0
    fi
}

##################
### MAIN START ###
##################

## Setting vector 'params' with all the parameters received by the script:
for ((i=1; i<=$#; i++)); do
    eval param="\${$i}"
    VectorAddElementNext params param
done

# Printing the vector 'params':
VectorPrint params

read temp

## Setting vector 'params2' with the elements of the vector 'params' in reversed order:
if [ -n "$params_0" ]; then
    for ((i=1; i<=$params_0; i++)); do
        count=$((params_0-i+1))
        VectorAddElement params2 count params_$i
    done
fi

# Printing the vector 'params2':
VectorPrint params2

read temp

## Getting the values of 'params2'`s elements and printing them:
if [ -n "$params2_0" ]; then
    echo "Printing the elements of the vector 'params2':"
    for ((i=1; i<=$params2_0; i++)); do
        eval current_elem_value=\"\$params2\_$i\"
        echo "params2_$i=\"$current_elem_value\""
    done
else
    echo "Vector 'params2' is empty!"
fi

read temp

## Creating a two dimensional array ('a'):
for ((i=1; i<=10; i++)); do
    VectorAddElement a 0 i
    for ((j=1; j<=8; j++)); do
        value=$(( 8 * ( i - 1 ) + j ))
        VectorAddElementDV a_$i $j $value
    done
done

## Manually printing the two dimensional array ('a'):
echo "Printing the two-dimensional array 'a':"
if [ -n "$a_0" ]; then
    for ((i=1; i<=$a_0; i++)); do
        eval current_vector_lenght=\$a\_$i\_0
        if [ -n "$current_vector_lenght" ]; then
            for ((j=1; j<=$current_vector_lenght; j++)); do
                eval value=\"\$a\_$i\_$j\"
                printf "$value "
            done
        fi
        printf "\n"
    done
fi

################
### MAIN END ###
################

#7


1  

One can simply define two functions to write ($4 is the assigned value) and read a matrix with arbitrary name ($1) and indexes ($2 and $3) exploiting eval and indirect referencing.

可以简单地定义两个函数来写($4是赋值的值),并读取一个带有任意名称的矩阵($1)和索引($2和$3),利用eval和间接引用。

#!/bin/bash

matrix_write () {
 eval $1"_"$2"_"$3=$4
 # aux=$1"_"$2"_"$3          # Alternative way
 # let $aux=$4               # ---
}

matrix_read () {
 aux=$1"_"$2"_"$3
 echo ${!aux}
}

for ((i=1;i<10;i=i+1)); do
 for ((j=1;j<10;j=j+1)); do 
  matrix_write a $i $j $[$i*10+$j]
 done
done

for ((i=1;i<10;i=i+1)); do
 for ((j=1;j<10;j=j+1)); do 
  echo "a_"$i"_"$j"="$(matrix_read a $i $j)
 done
done

#8


1  

If each row of the matrix is the same size, then you can simply use a linear array and multiplication.

如果矩阵的每一行都是相同的大小,那么你可以简单地使用一个线性数组和乘法。

That is,

也就是说,

a=()
for (( i=0; i<4; ++i )); do
  for (( j=0; j<5; ++j )); do
     a[i*5+j]=0
  done
done

Then your a[2][3] = 3 becomes

然后a[2][3] = 3就变成了。

a[2*5+3] = 3

This approach might be worth turning into a set of functions, but since you can't pass arrays to or return arrays from functions, you would have to use pass-by-name and sometimes eval. So I tend to file multidimensional arrays under "things bash is simply Not Meant To Do".

这种方法可能值得转换为一组函数,但是由于不能将数组从函数中传递或返回数组,因此必须使用passby -name,有时还需要eval。因此,我倾向于在“things bash根本不打算做”的情况下对多维数组进行归档。

#9


0  

For simulating a 2-dimensional array, I first load the first n-elements (the elements of the first column)

为了模拟二维数组,我首先加载第一个n元素(第一列的元素)

local pano_array=()  

i=0

for line in $(grep  "filename" "$file")
do 
  url=$(extract_url_from_xml $line)
  pano_array[i]="$url"
  i=$((i+1))
done

To add the second column, I define the size of the first column and calculate the values in an offset variable

要添加第二列,我定义第一个列的大小,并计算一个偏移量变量中的值。

array_len="${#pano_array[@]}"

i=0

while [[ $i -lt $array_len ]]
do
  url="${pano_array[$i]}"
  offset=$(($array_len+i)) 
  found_file=$(get_file $url)
  pano_array[$offset]=$found_file

  i=$((i+1))
done