2015-07-02 34 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

相关问题