2014-12-30 96 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

哇,你有一個短號碼!稍等片刻,我會將其添加到我的答案中。 –