![](/img/trans.png)
[英]shell script: how to correctly realize the following idea, defining variable names on the fly?
[英]How can I generate new variable names on the fly in a shell script?
我正在嘗試在 shell 腳本中生成動態 var 名稱,以在循環中處理一組具有不同名稱的文件,如下所示:
#!/bin/bash
SAMPLE1='1-first.with.custom.name'
SAMPLE2='2-second.with.custom.name'
for (( i = 1; i <= 2; i++ ))
do
echo SAMPLE{$i}
done
我希望輸出:
1-first.with.custom.name
2-second.with.custom.name
但我得到了:
SAMPLE{1}
SAMPLE{2}
是否可以即時生成 var 名稱?
您需要利用變量間接:
SAMPLE1='1-first.with.custom.name'
SAMPLE2='2-second.with.custom.name'
for (( i = 1; i <= 2; i++ ))
do
var="SAMPLE$i"
echo ${!var}
done
從Bash 手冊頁,在“參數擴展”下:
“如果參數的第一個字符是感嘆號 (!),則引入了一個變量間接級別。Bash 使用由參數的其余部分形成的變量的值作為變量的名稱;然后擴展這個變量,然后值用於替換的其余部分,而不是參數本身的值。這稱為間接擴展。”
您正在使用i的值,就好像它是一個數組索引。 不是,因為 SAMPLE1 和 SAMPLE2 是單獨的變量,而不是數組。
此外,在調用echo SAMPLE{$i}
您只是將i的值附加到單詞“SAMPLE”之后。 您在此語句中取消引用的唯一變量是$i ,這就是您得到結果的原因。
有兩種主要方法可以解決這個問題:
在這種情況下,最簡單的方法是使用eval :
SAMPLE1='1-first.with.custom.name'
SAMPLE2='2-second.with.custom.name'
for (( i = 1; i <= 2; i++ )); do
eval echo \$SAMPLE${i}
done
這會將i的值附加到變量的末尾,然后重新處理結果行,擴展插入的變量名稱(例如SAMPLE1或SAMPLE2 )。
這個問題的公認答案是:
SAMPLE1='1-first.with.custom.name'
SAMPLE2='2-second.with.custom.name'
for (( i = 1; i <= 2; i++ ))
do
var="SAMPLE$i"
echo ${!var}
done
從技術上講,這是一個三步過程。 首先,它為var分配一個內插變量名,然后解引用存儲在var 中的變量名,最后擴展結果。 它看起來更簡潔一些,有些人更喜歡這種語法而不是eval ,但結果基本相同。
您可以通過迭代數組而不是使用變量插值來簡化循環和擴展。 例如:
SAMPLE=('1-first.with.custom.name' '2-second.with.custom.name')
for i in "${SAMPLE[@]}"; do
echo "$i"
done
這比其他方法增加了好處。 具體來說:
所有三種方法都適用於原始問題中給出的示例,但數組解決方案提供了最大的整體靈活性。 選擇最適合您手頭數據的一種。
據我所知,
他們的方式@johnshen64 說。 此外,您可以使用這樣的數組來解決您的問題:
SAMPLE[1]='1-first.with.custom.name'
SAMPLE[2]='2-second.with.custom.name'
for (( i = 1; i <= 2; i++ )) do
echo ${SAMPLE[$i]}
done
請注意,您不需要使用數字作為索引SAMPLE[hello]
也能正常工作
您可以使用eval
,如下所示:
SAMPLE1='1-first.with.custom.name'
SAMPLE2='2-second.with.custom.name'
for (( i = 1; i <= 2; i++ ))
do
eval echo \$SAMPLE$i
done
不是一個獨立的答案,只是 Miquel 的答案的補充,我無法很好地發表評論。
您也可以使用循環、+= 運算符和 here 文檔來填充數組:
SAMPLE=()
while read; do SAMPLE+=("$REPLY"); done <<EOF
1-first.with.custom.name
2-second.with.custom.name
EOF
在 bash 4.0 中,它就像
readarray SAMPLE <<EOF
1-first.with.custom.name
2-second.with.custom.name
EOF
評估“回聲 $SAMPLE${i}”
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.