【问题标题】:how to parse a config file (*.conf) in shell script?如何在 shell 脚本中解析配置文件 (*.conf)?
【发布时间】:2014-05-06 04:04:40
【问题描述】:

我是 shell 脚本的新手。我有一个文件app.conf

[MySql]
user = root
password = root123
domain = localhost
database = db_name
port = 3306

[Logs]
level = logging.DEBUG

[Server]
port = 8080

我想在 shell 脚本中解析这个文件,并想从中提取 mysql 凭据。我怎样才能做到这一点?

【问题讨论】:

  • 您使用的是哪个外壳? bash, ksh, /bin/sh, ...?
  • 嗨@glennjackman,我是/bin/sh

标签: shell app-config sh readfile


【解决方案1】:

我会这样做:

pw=$(awk '/^password/{print $3}' app.conf)

user=$(awk '/^user/{print $3}' app.conf)


echo $pw
root123

echo $user
root

$() 将变量pw 设置为内部命令的输出。里面的命令会在 app.conf 文件中查找以 password 开头的行,然后打印该行中的第三个字段。

已编辑

如果您要从配置文件中解析出一堆值,我会为配置文件名创建一个变量:

CONFIG=app.conf
pw=$(awk '/^password/{print $3}' "${CONFIG}")
user=$(awk '/^user/{print $3}' "${CONFIG}")

以下是两个不同端口的操作方法...当您到达右侧部分时将标志设置为 1,并在找到端口时退出。

mport=$(awk '/^\[MySQL\]/{f=1} f==1&&/^port/{print $3;exit}' "${CONFIG}")
sport=$(awk '/^\[Server\]/{f=1} f==1&&/^port/{print $3;exit}' "${CONFIG}")

【讨论】:

  • 非常感谢,但我收到错误消息:user: not found。我的 shell 脚本文件是:#!/bin/sh user = $(awk '/^user/{print $3}' /root/app/config/app.conf)
  • 去掉等号周围的空格。
  • 您在 Windows 上吗?如果是这样,请尝试将单引号更改为双引号。如果失败,请尝试使用“cat -vet yourfile”检查您的文件是否有奇怪的字符。如果失败,请编辑您的答案并发布您遇到问题的确切代码,我会看看。
  • 非常感谢马克。这是工作。这是我理解你在说什么的愚蠢错误(显然我正在从 app.conf 中删除空格,因为我从没想过 shell 脚本中的赋值语句中的空格很重要)。现在我的理解是var=value$n 的shell 脚本中不允许有空格,这给了我第n 部分由空格分隔的行,该行由提供给awk 的正则表达式匹配。 $0 也会给我找到匹配项的整行。
  • 我在答案的末尾添加了一些提示...对于您的下一个问题 ;-)
【解决方案2】:

您需要搜索“shell ini 文件解析器”。我会从这样的开始:

ini_get () {
    awk -v section="$2" -v variable="$3" '
        $0 == "[" section "]" { in_section = 1; next }
        in_section && $1 == variable {
            $1=""
            $2=""
            sub(/^[[:space:]]+/, "")
            print
            exit 
        }
        in_section && $1 == "" {
            # we are at a blank line without finding the var in the section
            print "not found" > "/dev/stderr"
            exit 1
        }
    ' "$1"
}

mysql_user=$( ini_get app.conf MySql user )

【讨论】:

    【解决方案3】:

    使用 awk:

    awk -F ' *= *' '$1=="user"||$1=="password"{print $2}' my.cnf
    root
    gogslab
    

    【讨论】:

    • 是的,当然。此 awk 使用字段分隔符为 =,两侧可选空格。分隔字段后,当第一个字段为 userpassword 时,它会打印第二个字段
    【解决方案4】:

    我昨天遇到了一个类似的问题,并认为最好的解决方案可能是,如果你在解析文件后得到一个像“key - value”这样的关联数组。

    如果您想看一个运行示例,请查看https://github.com/philippkemmeter/set-resolution/blob/master/set-resolution

    适应您的问题,这可能有效:

    function receive_assoc_declare_statement {
        awk -F '=' 'BEGIN {ORS=" "}
        { 
            gsub(/[ \t]+/, "", $1); 
            gsub(/[ \t]+/, "", $2);
            print "[" $1 "]=" $2
        }' app.conf
    }
    
    eval 'declare -A CONF=('`receive_assoc_declare_statement`')'
    

    然后您可以通过${CONF[user]} 访问例如用户。

    gsub 正在修剪键和值,以便您可以使用制表符等来格式化您的配置文件。

    它缺少部分,但您可以使用 sed 添加此功能,为每个部分创建一个配置数组:

    sed -n '/\[MySql\]/, /\[/ {p}' test.removeme | sed '1 d; $ d'
    

    所以总的来说回答你的问题,这个脚本可能会起作用:

    MYSQL=`sed -n '/\[MySql\]/, /\[/ {p}' app.conf | sed '1 d; $ d' | awk -F '=' 'BEGIN {ORS=" "}
    {
        gsub(/[ \t]+/, "", $1); 
        gsub(/[ \t]+/, "", $2);
        print "[" $1 "]=" $2
    }' `
    eval 'declare -A MYSQL=('$MYSQL')'
    

    其他部分对应。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-18
      • 2011-06-28
      • 1970-01-01
      • 1970-01-01
      • 2011-12-31
      • 2016-06-21
      相关资源
      最近更新 更多