如何在Shell脚本中解析配置文件(*.conf)?

11

我刚开始学习 shell 脚本。我有一个名为 app.conf 的文件,内容如下:

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

[Logs]
level = logging.DEBUG

[Server]
port = 8080

我想在shell脚本中解析这个文件,并从中提取mysql凭据。 我该如何实现?


你使用的是哪个shell?bash、ksh、/bin/sh等等? - glenn jackman
嗨@glennjackman,它是/bin/sh - exAres
4个回答

12

我会这样做:

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

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


echo $pw
root123

echo $user
root

$()将变量pw设置为其中命令的输出。命令会查找您的app.conf文件中以password开头的一行,并打印该行中第3个字段。

编辑内容:

如果您要从配置文件中解析一堆值,我建议先将配置文件名赋值给一个变量:

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}")

移除等号周围的空格。 - Mark Setchell
1
你是在使用Windows吗?如果是的话,请尝试将单引号改为双引号。如果这样还不行,请使用"cat -vet yourfile"命令检查文件是否有奇怪的字符。如果还是不行,请编辑你的回答并发布你遇到问题的确切代码,我会帮你看一下。 - Mark Setchell
非常感谢,Mark。它正在运行。这是我对你所说的理解上犯的愚蠢错误(显然,我从未想过在shell脚本的赋值语句中删除空格会产生影响)。现在我明白了,在shell脚本中不允许有空格出现在var=value中,并且$n会给我提供由正则表达式匹配到的一行中以空格分隔的第n部分。另外,$0会给我提供匹配到的整行内容。 - exAres
没错!你正在走向成功——祝你愉快的Shell脚本编写! - Mark Setchell
1
我在我的答案末尾添加了一些提示……为你的下一个问题;-) - Mark Setchell
显示剩余2条评论

6

您需要搜索“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 )

5

使用awk:

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

当然可以。这个awk使用字段分隔符作为=,两侧可以选择性地加上空格。一旦字段被分隔,它会在第一个字段为userpassword时打印第二个字段。 - anubhava

2

我昨天遇到了类似的问题,认为最好的解决方案是,在解析文件后获得一个“键-值”形式的关联数组。

如果您想看一个运行示例,请查看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会修剪键和值,以便您可以使用tab等格式化配置文件。

它缺少部分功能,但是您可以使用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')'

其他部分相应对应。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接