2015-07-02 37 views
1

我想在分組中創建一個包含key = value對的配置文件,以便我可以在key = value對的組中循環訪問配置文件。在配置文件中讀取最乾淨/最簡單的方法

實施例的配置文件:

#group1 
var1=test1 
var2=test2 
var3=test3 

#group2 
var1=text4 
var2=text5 
var3=test6 
var4=test7 

#group3 
var3=test8 

有一種簡單的方法來解析類似於此佈局,其中每個基團可以包含/排除的參數的配置文件,並解析循環的每次迭代將在特定拉組鍵=值對?

bash是否有內置的配置解析器?這是一個openrc初始化腳本。

+2

這個問題是相似的:http://stackoverflow.com/questions/3410306/bash-read-in-config-file-帶同一變量的多個實例?rq = 1只需要在看到區域標題時開始處理行,並在到達下一個標題時停止。 – Barmar

+0

@randy,你的分組中有重複的鍵。這是打算或僅僅是一個例子。前者可以group1和group2有單獨的變量? –

+0

如果你可以控制配置文件格式,而不是處理一個你必須解析的文件,那麼使用'source'格式編寫配置要容易得多。引入**關聯數組**可以帶來更大的靈活性。例如。 ('declare -A group1; group1 =([var1] =「test 1」[var2] =「test 2」...)')。然後,而不是解析它,只是'。/path/to/my/config「,然後簡單地使用'$ {group1 [var2]}'等等。 –

回答

1

建立在在this thread的答案,你可以這樣做:

#! /bin/bash 

if [ -f "${HOME}/.${0##*/}" ]; then 
    config="${HOME}/.${0##*/}rc" 
else 
    config="/etc/${0##*/}" 
fi 

if [ -f "$config" ]; then 
    section=global 
    while read -r line; do 
     if [[ $line =~ ^(#|$) ]]; then continue; fi 
     if [[ $line =~ ^\[[[:alpha:]_][[:alnum:]_]*\]$ ]]; then 
      section=${line#[} 
      section=${section%]} 
     elif [[ $line =~ ^[[:alpha:]_][[:alnum:]_]*= ]]; then 
      eval "${section}_${line%%=*}"=\${line#*=} 
     fi 
    done <"$config" 
fi 

這假設bash,並解析配置文件是這樣的:

# comment 

global1=gval1 
global2=gval2 

[section1] 
variable_1=value_11 
variable_2=value_12 

[section2] 
variable_1=value_21 
variable_2=value_22 

它設置在配置文件中指定的變量,通過該部分的名稱爲前綴的名字。評論和空白行被忽略。

概念證明:

set | egrep '^(global|section)[^=]' | \ 
while read -r line; do 
    key=${line%%=*} 
    eval "val=\${$key}" 
    printf '%s = [%s]\n' "$key" "$val" 
done 

輸出:

global_global1 = [gval1] 
global_global2 = [gval2] 
section1_variable_1 = [value_11] 
section1_variable_2 = [value_12] 
section2_variable_1 = [value_21] 
section2_variable_2 = [value_22] 
1

您可以使用命令cut使用等號=作爲分隔符

如果$line是每一個有效行,(可以躲過開始的行註釋和空行)

key=`cut -f1 -d '=" $line` 
value=`cut -f2 -d '=" $line` 
+0

這不適用於他的例子中的分組。如果他想要group2而不是group3的'var1'?如果它和你的答案一樣簡單,那麼他可以直接輸入文件。 – jordanm

+0

@jordanm,好點。我已經要求作者提供一些內容 –

+0

而且,這比僅使用'read':'IFS ='='讀取鍵值<<<「$ line」'要低效。 – chepner

相關問題