2014-12-30 93 views
1

如何传递2d数组以在shell脚本中运行? 我需要传递矩阵的功能,但它不工作shell脚本将2D数组传递到函数

tr(){ 
matrix="$3" 
num_rows="$1" 
num_columns="$2" 
f1="%$((${#num_rows}+1))s" 
f2=" %9s" 
for ((i=1;i<=num_rows;i++)) do 
for ((j=1;j<=num_columns;j++)) do 
    echo -ne "${matrix[$i,$j]}\t" 
    done 
echo -e "\n" 
done 


tr $rows $columns $x 
+1

击[支持一维数组(http://www.gnu.org/软件/ bash/manual/html_node/Arrays.html),所以你必须实现你自己的多维索引方案。 – Fizz

+0

怎么可能在bash中做到这一点? – promise

+0

任何你可以在2d数组中做的事情,你可以在1d中做一些工作。 –

回答

4

使用关联数组:

declare -A matrix 

然后,事情像矩阵[6,7] = 42将工作,因为“6,7- “ist只是一个字符串,而关联数组接受字符串作为索引。你不妨写下如下的东西:

matrix[one,two]=three 
matrix[yet,another,dimension]="Perry Rhodan" 

你可以在[和]之间写任何字符串。以下是如何使用它的完整示例。

#!/bin/bash 
# 
# Example for a function that accepts the name of an associative array ... 
# ... and does some work on the array entries, e.g. compute their sum 
# We assume that all *values* of the array are integers - no error check 

sum() { 
    local s=0     # we don't want to interfere with any other s 
    declare -n local var="$1" # now var references the variable named in $1 
    for value in "${var[@]}" # value runs through all values of the array 
    do 
     let s+="$value" 
    done 
    echo sum is $s 
} 

declare -A m # now m is an associative array, accepting any kind of index 

m[0,0]=4  # this looks like 2-dimensional indexing, but is is not 
m[2,3]=5  # m will accept any reasonable string as an array index 
m[678]=6  # m does not care about the number of commas between numbers 
m[foo]=7  # m does not even care about the indices being numbers at all 

sum m 

正如你所看到的,矩阵m不是真的有2维。它只是将任何字符串作为索引,只要它不包含某些shell语法字符,并且逗号在字符串中是允许的。

请注意参考声明-n ... - 这允许从函数内简单访问矩阵,最重要的是,无需知道矩阵的名称。因此,您可以为不同名称的几个矩阵调用该函数。

关键字本地很重要。这意味着,返回时,var会自动取消设置。否则,你将有一个参考“var”到一个关联数组。如果你以后想要使用var,将很难使用它,因为除了关联数组外,不能将其用作其他任何内容。如果你试图用“unset var”来摆脱它,bash会记得var指的是m,并删除你的矩阵m。通常,尽可能在函数中设置变量。它甚至允许我重新使用一个名字。例如,在函数内使用“s”作为变量名可能会显得很危险,因为它可能会更改全局变量“s”的值。但它不是 - 通过声明它是本地的,函数有它自己的私有变量s,并且任何可能已经存在的s都是未触及的。

就像一个示范:如果你想看到的数组索引在回路中,做到这一点:只有

sum() { 
    local s=0     # we don't want to interfere with any other s 
    declare -n local var="$1" # now var references the variable named in $1 
    for i in "${!var[@]}"  # !var means that we run through all indices 
    do      # we really need a reference here because ... 
     let s+=${var["$i"]} # ... indirections like ${!$1[$i]} won't work 
    done 
    echo sum is $s 
} 
+0

这是真的,但那么你会如何将它传递给函数? – user000001

+0

哇,你有一个短号码!稍等片刻,我会将其添加到我的答案中。 –