2011-01-13 30 views
4

ユーザ入力が必要なBashメニュースクリプトをセットアップしました。外部ファイルからBash読み込み配列

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

今、私は何を達成しようとしていますが、このようにちょっとスクリプトからvar.txtから読み取ることができるようにすることです: これらの入力は、そのようvar.txtという名前のテキストファイルが(に追加)書いています:

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

今私はそれを例として使っていないことを知っています。事前に

おかげで、 ジョー

答えて

3

変数抽出を関数にカプセル化し、関数内で使用するときにdeclareがローカル変数を作成するという事実を利用できます。このテクニックは、関数が呼び出されるたびにファイルを読み込みます。あなたが行うことができ

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}}; 
} 

含む "データ" と呼ばれるファイルを考えると

readvar() { 
    # call like this: readvar filename variable 
    while read -r line 
    do 
     # you could do some validation here 
     declare "$line" 
    done < "$1" 
    echo ${!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 

このようにすると、関数を1回呼び出すだけで、個々のクエリを作成する代わりに配列全体を使用できるようになります。

+0

うわー!ありがとう、私はまだこれらをテストする機会がありませんでしたが、これは私が達成しようとしているもののために最も確実に機能すると確信しています。自動化されたサーバのインストールと設定 - システムを再現する必要があります!これらをテストするために週末に時間があるべきです。両方のおかげで! – jmituzas

+0

すごくうまくいった!ありがとう – jmituzas

+1

@jmituzas:Bash 4には、 "mapfile"の同義語である "readarray"と呼ばれる組み込み関数があります。これらのコマンドは、ファイルの行を配列に読み込みます。彼らは私の答えに示されているように可変設定をしませんが、あなたはおそらくその技術を融合させることができます。 –

5

全体var.txtファイルは、あなたが、あなただけの新しいbashスクリプトでこれらの変数を使用できるようにするには、sourceそれにできるかもしれません示されているようにのみバッシュ互換の変数の割り当てが含まれている場合:

source var.txt 

useradd ${input[1]} 

ただし、既存の変数はすべて同じ名前で上書きされます。 Command substitutionは、特定の変数を選択することで、これを回避するために使用することができます。

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

あなたが興味のある各変数のためにこれを行う必要がありますが、それは、名前変更変数が可能になります。基本的には、var.txtファイルから変数の値を抽出し、それを新しい変数に割り当てます。それらの使用の詳細については、grep manual pageおよびsed info pageを参照してください。

Process substitutionはシンプルな表現を可能にする:あなたは、不要な変数の上書きを監視するために持っているが

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

useradd ${input[1]} 

これは、あなたが興味の定義のみをインポートすることが可能になります。

+0

私は約1時間で家に帰るとき、恐ろしいことがあります。はい、Bashと互換性のある変数の割り当てのみが含まれています。 – jmituzas

+0

これらのリンクのおかげで本当に役に立つ情報がたくさんあります。 – jmituzas

13

bash's readarray statementを使用してください。 (これは、配列要素に動的にスペースを入れる唯一の方法です)配列の要素を各行に1つずつ含み、代入文を含まないためには、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変数が範囲外にスコープされているためだと思います。

関連する問題