Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在shell脚本中解析配置文件(*.conf)?_Shell_App Config_Sh_Readfile - Fatal编程技术网

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

如何在shell脚本中解析配置文件(*.conf)?,shell,app-config,sh,readfile,Shell,App Config,Sh,Readfile,我不熟悉shell脚本。我有一个文件app.conf如下: [MySql] user = root password = root123 domain = localhost database = db_name port = 3306 [Logs] level = logging.DEBUG [Server] port = 8080 我想用shell脚本解析这个文件,并从中提取mysql凭据。如何实现这一点?使用awk: awk -F ' *= *' '$1=="user"||$1=="

我不熟悉shell脚本。我有一个文件
app.conf
如下:

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

[Logs]
level = logging.DEBUG

[Server]
port = 8080
我想用shell脚本解析这个文件,并从中提取mysql凭据。如何实现这一点?

使用awk:

awk -F ' *= *' '$1=="user"||$1=="password"{print $2}' my.cnf
root
gogslab
我会这样做:

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

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

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

我希望您能看到一个正在运行的示例

根据您的问题,这可能会起作用:

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`')'
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')'
然后,您可以通过
${CONF[user]}
访问例如user的实例

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

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

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

因此,总体上回答您的问题,这个脚本可能会起作用:

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`')'
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')'

其他部分相应。

是,当然。此awk将字段分隔符用作
=
,并在两侧使用可选空格。一旦字段被分离,当第一个字段是
用户
密码
时,它将打印第二个字段。非常感谢,但我收到一个错误:
用户:未找到
。我的shell脚本文件是:
#/bin/sh user=$(awk'/^user/{print$3}'/root/app/config/app.conf)
删除等号周围的空格。您在Windows上吗?如果是这样,请尝试将单引号更改为双引号。如果失败了,试着用“cat-vet yourfile”检查你的文件是否没有奇怪的字符。如果失败了,请编辑你的答案,并发布你遇到问题的确切代码,我会看一看。非常感谢马克。它正在工作。这是我在理解您所说的内容时犯的愚蠢错误(显然我是在从app.conf中删除空格,因为我从来没有想到shell脚本中赋值语句中的空格会起作用)。现在我所理解的是,shell脚本中不允许使用空格来表示
var=value
,而
$n
在与提供给awk的正则表达式匹配的行中,给出了由空格分隔的第n部分。另外,
$0
会给出找到匹配项的整行代码。我在回答的末尾添加了一些提示。。。关于下一个问题;-)你用的是哪个外壳?bash,ksh,/bin/sh,…?嗨@glennjackman,这是
/bin/sh