2011-01-13 177 views
4

我已經設置了一個Bash菜單腳本,它也需要用戶輸入。 這些輸入寫(附加)命名var.txt像這樣的文本文件:Bash從外部文件讀取數組

input[0]='192.0.0.1' 
input[1]='username' 
input[2]='example.com' 
input[3]='/home/newuser' 

現在我所要完成的是能夠從var.txt從腳本還挺閱讀這樣的:

useradd var.txt/${input[1]} 

現在我知道,不會僅僅使用它的例子。

由於事先 喬

回答

3

您可以封裝您的變量中抽取功能,走的事實,即declare函數內使用時產生的局部變量。每次調用該函數時,該技術都會讀取該文件。

readvar() { 
    # call like this: readvar filename variable 
    while read -r line 
    do 
     # you could do some validation here 
     declare "$line" 
    done < "$1" 
    echo ${!2} 
} 

給出一個所謂的 「數據」 包含文件:

input[0]='192.0.0.1' 
input[1]='username' 
input[2]='example.com' 
input[3]='/home/newuser' 
foo=bar 
bar=baz 

你可以這樣做:

$ a=$(readvar data input[1]) 
$ echo "$a" 
username 
$ readvar data foo 
bar 

這將讀取的數組並將其重命名:

readarray() { 
    # call like this: readarray filename arrayname newname 
    # newname may be omitted and will default to the existing name 
    while read -r line 
    do 
     declare "$line" 
    done < "$1" 
    local d=$(declare -p $2) 
    echo ${d/#declare -a $2/declare -a ${3:-$2}}; 
} 

示例:

$ eval $(readarray data input output) 
$ echo ${output[2]} 
example.com 
$ echo ${output[0]} 
192.0.0.1 
$ eval $(readarray data input) 
$ echo ${input[3]} 
/home/newuser 

這樣做,你只需要對函數進行一次調用,整個數組就可以使用,而不必進行單獨的查詢。

5

如果整個var.txt文件包含爲你指出,你可能只是能夠source它,使這些變量可以在一個新的bash腳本只bash兼容的變量賦值:

source var.txt 

useradd ${input[1]} 

但是,這將覆蓋任何具有相同名稱的現有變量。 Command substitution可以用來避免這種情況,通過選擇特定的變量:

input[1]="$(grep '^input\[1\]=' var.txt | sed "s|[^=]*='\(.*\)'|\1|")" 

它允許重新命名變量,但你必須爲每個感興趣的變量做到這一點。它基本上從var.txt文件中提取變量的值並將其分配給一個新變量。有關其使用的更多信息,請參閱grep manual pagesed info page

Process substitution可允許簡單的表達式:

source <(grep '^input\[[0-9]*\]=' var.txt) 

useradd ${input[1]} 

這將允許用戶導入的興趣只定義,雖然你看不想要的變量覆蓋。

+0

真棒會嘗試當我約一小時回家。是的,它只包含Bash兼容的變量賦值。 – jmituzas 2011-01-13 21:26:20

+0

感謝那些鏈接,那裏有很多真正有用的信息。 – jmituzas 2011-01-13 21:36:09

13

使用bash's readarray statement。 (這是我能找到把數組元素的空間動態的唯一方式。)你需要你的var.txt文件只包含在每一行的陣列,社會的因素,不含有賦值語句。

readarray -t input < var.txt 

欲瞭解更多信息,請help readarray(然後會告訴你去嘗試help mapfile)。

這裏是我的測試吧:

echo -e "a\nb c\nd" > var.txt 
readarray input < var.txt 
for item in "${input[@]}"; do echo $item; done 

打印:

a 
b c 
d 

注意:做cat var.txt | readarray -t input不起作用。我認爲這是因爲input變量的範圍不可觸及。