2017-04-09 273 views
3

我想從Bash變量中讀取我知道其名稱後綴的變量,但我想遍歷前綴。用動態名稱檢查Bash變量

我在下面給出一個例子:

var1_name="variable1" 
var1_size="2" 
var2_name="variable2" 
var2_size="3" 
vars=(var1 var2) 

for v in "${vars[@]}" 
do 
    echo $v_name 
    echo $v_size 
done 

和我所要的輸出看起來像如下:

variable1 
2 
variable2 
3 

是否有任何與巴什做到這一點? 我已經嘗試過eval和關聯數組,但我仍然找不到一種方法來檢查已定義的變量。

回答

3

以下適用於我。您需要首先構造變量,然後使用感嘆號對其進行評估。

var1_name="variable1" 
var1_size="2" 
var2_name="variable2" 
var2_size="3" 
vars=("var1" "var2") 

for v in "${vars[@]}" 
do 
    name=${v}_name 
    size=${v}_size 
    echo ${!name} 
    echo ${!size} 
done 

O/P

variable1 
2 
variable2 
3 
+0

謝謝!這正如我想要的那樣工作! –

2

auhuman's helpful answer正是解決您的問題,問。

這裏不需要你先指定一個數組名稱前綴假設感興趣的所有變量都具有相同前綴名稱,如var替代,

for name in "${[email protected]}" # Loop over all variables whose names start with 'var'. 
do 
    [[ $name =~ ^var[0-9]+_(name|size)$ ]] || continue # Ignore unrelated names. 
    echo "${!name}" # Use variable indirection to print the variable's value. 
done 
  • 代碼使用形式擊變量間接的,全部基於語法${!...}

    • "${[email protected]}"字面基於列表形式:它擴大到列表(陣列)的名的所有定義的變量,其名稱有文字前綴var(他們的名字開始於var),如果有的話。由於只有一個文字被允許先@,使用模式,如
      "${!var[0-9][email protected]}"用於更復雜的匹配確實工作,很遺憾。

      • 實施例:for varName in "${[email protected]}"; do echo "$varName"; done
        產生HOSTNAMEHOSTTYPE,例如。

      • 相關的${!var*}語法(沒有雙引號)似乎工作相同。 (奇怪的是,man頁面聲稱$IFS值的第一個字符用於連接匹配的名稱,如果該第一個字符只在for循環中按預期方式工作,那麼該值只能按預期工作。是一個空白字符。 ($IFS默認值爲真,以空格開頭),但實際上始終使用空間,與$IFS的值無關;與([email protected]; echo ${!HOST*})驗證)

    • ${!name},所述可變爲基礎的標量形式,膨脹到其名稱存儲爲$name的值的變量的值。

      • 例如:var='value'; name='var'; echo ${!name}得到value

      • 注:一招(上面使用),你可以用間接的方式得到陣列的價值觀太,即通過附加的所有指數中索引表達式[@]到的名稱可變間接引用;例如:
        arr=(one two three); name='arr[@]'; echo "${!name}" 收率one two three;訪問一個特定的元素這種方式(例如,name='arr[1]')的工作原理也一樣,但提取元件的範圍確實(例如,name='arr[@]: 0:2')。

    • 還有一個陣列索引列表形式 - 上面未使用 - 其擴展到一個給定的陣列/關聯數組的索引/密鑰的列表(數組)。

      • 實施例:arr=(one two three); echo "${!arr[@]}"
        產生0 1 2,所述陣列的所述隱式連續索引。

      • 它與顯式分配的索引的工作原理類似地(例如,
        arr=([10]=one two three); echo "${!arr[@]}"),或者在擊V4 +,與締合陣列(儘管,如關聯數組的性質,鍵不能保證在順序列出他們被定義;例如,
        declare -A aarr=([one]=1 [two]=2); echo "${!aarr[@]}")。

  • [[ $v =~ ^var[0-9]+_(name|size)$ ]]使用=~操作者的變量名稱在手對陣上RHS上的擴展正則表達式以確定它是否是所關注的名稱。

+1

我實際上不使用名稱var1,var2 ...它有點不同,但它對於我在該腳本中做類似的事情可能非常有用,謝謝! –

+0

@OfriRips:理解,謝謝。我已經說得更清楚了,我的答案假定共享名稱前綴(並且我添加了變量間接的概述)。感謝您回來並接受auhuman的回答。還請考慮重溫您的舊問題,看看那裏的答案是否應該被接受。 – mklement0