2011-07-01 51 views
3

我想要構造變量名N_fooN_bar和使用它們的值如下:如何在Bash中構造變量名?

#!/bin/bash 
N_foo=2 
N_bar=3 
for i in { "foo" "bar" } 
do 
    for j in { 1..$(`N_$i`) } 
    do 
     echo $j 
    done 
done 

我想使用的N_fooN_bar的值在兩個內環並打印出1,2和1, 2,3。什麼是正確的語法?

+0

首先,您必須從外部刪除'{''}'並在內部循環中的{}'旁邊移除空格。 'echo {1..3}'不會產生你想要的。 – Lynch

+0

數組是避免這種「eval」地獄的最好方法。你究竟在做什麼? –

回答

5
#!/bin/bash 
N_foo=2 
N_bar=3 
for i in "foo" "bar" 
do 
    key="N_${i}" 
    eval count='$'$key 
    for j in `seq 1 $count` 
    do 
     echo $j 
    done 
done 
+0

'eval'是解決這類問題的經典解決方案。 –

+0

@Computist:我拒絕了你對這個答案的編輯。答案沒有使用你詢問的'$ {!symbol}'語法。你的編輯確實是一個新問題。如果您決定不爲此打開新的問題,則應編輯自己的問題而不是答案。 –

+0

請注意,您不需要內循環 - 「seq 1 $ count」就足夠了。 – a3nm

3

可以使用間接變量引用操作:

var="foo" 
nfoo=1 
ref=n${var} 
echo $ref 
echo ${!ref} 

哪個給出了這樣的輸出:

nfoo 
1 
+0

但這仍然無法解決它。 –

+0

Ignacio:是的你是對的 - 沒有像我期望的那樣在for循環範圍大括號中使用它。 {1 .. $ {!var}}沒有像我想的那樣創建一個範圍...... – sashang

5
#!/bin/bash 
N_foo=2 
N_bar=3 
for i in "foo" "bar" 
do 
    i2="N_$i" 
    seq 1 ${!i2} 
done 
+0

好得多(並且比接受的答案更簡潔)。謝謝。 – dimitarvp

+0

不確定「更好」 - 'seq'不可移植,不由POSIX指定,也不包含在bash中。 –

0

我結束了使用下面的代碼。它使用參數替代技術(c.f. http://tldp.org/LDP/abs/html/parameter-substitution.html)。

#!/bin/bash 
N_foo=2 
N_bar=3 
for i in "foo" "bar" 
do 
j_max=N_$i 
for ((j=1; j<=${!j_max}; j++)) 
    do 
    echo $j 
    done 
done 

!是歷史擴展參數(C.F. http://www.gnu.org/software/bash/manual/bashref.html#Special-Parameters)。 !j_max將被替換爲設置爲j_max的最近值,即N_foo/N_bar在第1次/第2次迭代中。然後在第一次/第二次迭代中調用${N_foo}/${N_bar}其值爲2/3。

+0

請避免鏈接到ABS - 這是bash的W3Schools,充滿了不良實踐例子和過時的內容。考慮[bash-hacker的間接維基](http://wiki.bash-hackers.org/syntax/pe#indirection)或[BashFAQ#6](http://mywiki.wooledge.org/BashFAQ/ 006)。 –