2016-09-09 16 views
0

私はbashスクリプト作成に数週間しかいませんが、私はまだこの問題に巻き込まれてしまっています。どんな助けもありがとう!私は配列にこのscript.confファイルの内容を読みたい、bashスクリプトで値が複数の行にまたがっている場合、ファイルからキー値のペアを抽出する方法はありますか?

key1=value1 
key2=${HOME}/Folder 
key3=("k3v1" "k3 v2" "k3v3") 
key4=("k4v1" 
    "k4 v2" 
    "k4v3" 
) 
key5=value5 
#key6="Do Not Include Me" 

は、私が「 script.conf」次を含むファイルを持っています。私はキー1,2,3,5のシナリオをどのように扱うかを学んだが、 key4シナリオは複数の行にまたがってレンチを投げている。

私はsed -n '/=\s*[(]/,/[)]/{/'の使用を検討していますが、これはkey4とその値をキャプチャしますが、これを混ぜ合わせて他のキーもマッチでキャプチャする方法はわかりません。範囲の構文も私には新しかったので、キー/値を分ける方法はわかりませんでした。私は平易なテキストで簡単な正規表現があるように思えます。平文で "パターンを見つけてグループ化して(キーのために)、次に '='文字の後にすべてをグループ化して別の^(.*)=が見つかるまで、リンスとリピート "。私はこれをすれば、私はキーと値の分離(私は応答を待っている間これを調べているだろう)を処理しないように、私は読んでいる行を変更する必要がありますね。ところで、私は、key4の値が平らになっている(新しい行が削除された)解決策が受け入れられるだろうと思う。私はkey3を知っています。文字列として値を格納してから、配列要素にリストを含めることができないので、後で繰り返し処理を行う必要があります。

sedで正しいパスにあるのですか、これはawkや他のツールの仕事ですか? (私はまだawkに挑戦していない)。 LoadConfigFile関数のwhile read行を変更するなど、私が森林に入り込むには余裕があるので、私が見逃している簡単なアプローチはありますか?ここで

は私が処理し、$コンフィグ配列に他のペアを取得するためscript.shで、これまで持っているコードです:私は前に述べたように

__AppDir=$(dirname $0) 
__AppName=${__ScriptName%.*} 


typeset -A config #init config array 
config=( #Setting Default Config values 
    [key1]="defaultValue1" 
    [key2]="${HOME}/defaultFolder" 

    [QuietMode]=0 
    [Verbose]=0  #Ex. Usage: [[ "${config[Verbose]}" -gt 0 ]] && echo ">>>Debug print" 
) 

function LoadConfigFile() { 
    local cfgFile="${1}" 
    shopt -s extglob #Needed to remove trailing spaces 
    if [ -f ${cfgFile} ]; then 
     while IFS='=' read -r key value; do 
      if [[ "${key:0:1}" == "#" ]]; then 
       #echo "Skipping Comment line: ${key}" 
      elif [ "${key:-EMPTY}" != "EMPTY" ]; then 
       value="${value%%\#*}" # Delete in-line, right comments 
       value="${value%%*()}" # Delete trailing spaces 
       value="${value%%()*}" # Delete leading spaces 
       #value="${value%\"*}" # Delete opening string quotes 
       #value="${value#\"*}" # Delete closing string quotes 

       #Manipulate any variables included in the value so that they can be expanded correctly 
       # - value must be stored in the format: "${var1}". `backticks`, "$var2", and "doubleQuotes" are left as is 
       value="${value//\"/\\\"}" # Escape double quotes for eval 
       value="${value//\`/\\\`}" # Escape backticks for eval 
       value="${value//\$/\\\$}" # Escape ALL '$' for eval 
       value="${value//\\\${/\${}" # Undo the protection of '$' if it was followed by a '{'   
       value=$(eval "printf '%s\n' \"${value}\"") 

       config[${key}]=${value} #Store the value into the config array at the specified key     
       echo " >>>DBG: Key = ${key}, Value = ${value}" 
      #else 
      # echo "Skipped Empty Key" 
      fi 

     done < "${cfgFile}" 
    fi 
} 

CONFIG_FILE=${__AppDir}/${__AppName}.conf 
echo "Config File @ ${CONFIG_FILE}" 

LoadConfigFile ${CONFIG_FILE} 

#Print elements of $config 
echo "Script Config Values:" 
echo "----------------------------" 
for key in "${!config[@]}"; do  #The '!' char gets an array of the keys, without it, we would get an array of the values 
    printf " %-20s = %s\n" "${key}" "${config[${key}]}" 
done 
echo "------ End Script Config ------" 

#To convert to an array... 
declare -a valAsArray=${config[RequiredAppPackages]} #Convert the value from a string to an array 
echo "Count = ${#valAsArray[@]}" 
for itemCfg in "${valAsArray[@]}"; do 
    echo " item = ${itemCfg}" 
done 

、私はちょうどに始めていますbashとLinuxスクリプトを一般的に学ぶので、コードの他の部分でタブーなことをしているのを見たら、コメントにフィードバックをお寄せください。私は悪い習慣を早期に開始したくありませんon :-)

*重要な場合は、OSはUbuntu 14.04です。

EDIT:要求されたよう 、script.confファイルを読んだ後、私は次のように相当すると$config[@]の要素のための希望:

typeset -A config #init config array 
config=( 
    [key1]="value1" 
    [key2]="${HOME}/Folder" 
    [key3]="(\"k3v1\" \"k3 v2\" \"k3v3\")" 
    [key4]="(\"k4v1\" \"k4 v2\" \"k4v3\")" 
    [key5]="value5" 
) 

私が変換できるようにしたいです配列に要素のKEY4」と「KEY3」の値は、次のコードでそれらの上に同じように反復:

declare -a keyValAsArray=${config[keyN]} #Convert the value from a string to an array 
echo "Count = ${#keyValAsArray[@]}" 
for item in "${keyValAsArray[@]}"; do 
    echo " item = ${item}" 
done 

私は、\ nをKEY4のVAのために保存されている場合、それは重要とは思いませんそれが問題になるかどうかは、declareに依存しています。

+1

設定ファイルはオプションではありませんか? –

+1

バッシュパーサーのバグのサブセットを実装するのではなく、単にファイルを_source_しないでください。 –

+0

シェルを使用して制限されていますか?そのような作業のために私は別の言語*(Python、Perl、...)を使用します。 – MarcoS

答えて

0

シェルは、これらの呼び出しを順序付けるための言語を持つツールを呼び出すための環境です。テキストを操作するツールではありません。テキストを操作する標準のUNIXツールはawkです。シェル内のテキストを操作しようとすると悪い習慣ですwhy-is-using-a-shell-loop-to-process-text-considered-bad-pr‌​actice理由のいくつかについて

あなたはまだ私がわからないようにconfig配列を設定する予想される結果を投稿していませんが、欲しかっ:

$ cat tst.sh 
declare -A config="($(awk ' 
    { gsub(/^[[:space:]]+|([[:space:]]+|#.*)$/,"") } 
    !NF { next } 
    /^[^="]+=/ { 
     name = gensub(/=.*/,"",1) 
     value = gensub(/^[^=]+=/,"",1) 
     n2v[name] = value 
     next 
    } 
    { n2v[name] = n2v[name] OFS $0 } 
    END { 
     for (name in n2v) { 
      value = gensub(/"/,"\\\\&","g",n2v[name]) 
      printf "[%s]=\"%s\"\n", name, value 
     } 
    } 
    ' script.conf 
))" 

declare -p config 

$ ./tst.sh 
declare -A config='([key5]="value5" [key4]="(\"k4v1\" \"k4 v2\" \"k4v3\")" [key3]="(\"k3v1\" \"k3 v2\" \"k3v3\")" [key2]="/home/Ed/Folder" [key1]="value1")' 

上記は(gensubのためにGNU AWKを使用しています)、その他のawksであなたの代わりに[G]サブを()を使用すると思います。

+1

答えをありがとう。私はあなたのコードをまだ試してみる機会がありませんでした...うまくいけば、今日の午後。必要に応じてすべてがうまくいけば、これを正解とマークするために戻ってきます。そうでない場合は、私が必要とするものの例を使って、より明確にしようとします。 –

+0

@JerrenSaundersがあなたのために働いたのですか? –

+0

閉じる必要はありません。私はうまくいけばもっと明確になる別の編集に取り組んでいます。 –

関連する問題