使用shell迭代yaml



我有一个config_file.yml文件,如下所示:

sample:
sql: "select * from dbname.tableName where sampleDate>='2018-07-20';"
config: {'hosts': [!!python/tuple ['192.162.0.10', 3001]]}
sample2:
sql: "select * from dbname.tableName where sampleDate<='2016-05-25';"
config: {'hosts': [!!python/tuple ['190.160.0.10', 3002]]}

我想使用shell脚本迭代它的键值对,直到EOF。基本上,我希望能够迭代每个sql直到EOF,并在shell循环中执行每个sql。

试着浏览了很多文档,但他们没有足够的信息来使用shell循环通过yaml。

任何想法或例子都会很有帮助。。。

谢谢!

编辑:

我已经在使用->

parse_yaml() {
local prefix=$2
local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '34')
sed -ne "s|^($s)($w)$s:$s"(.*)"$s$|1$fs2$fs3|p" -e "s|^($s)($w)$s:$s(.*)$s$|1$fs2$fs3|p" $1 |
awk -F$fs '{
indent = length($1)/2;
vname[indent] = $2;
for (i in vname) {
if (i > indent) {delete vname[i]}}
if (length($3) > 0) {
vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
printf("%s%s%s="%s"n", "'$prefix'",vn, $2, $3);
}
}'
}
# read yaml file
eval $(parse_yaml config_file.yml "")
# access yaml content
echo $sample_sql

我不明白我该如何迭代。

您不能使用python的原因是什么?

它应该与大多数linux发行版一起预装,这意味着你不必重新发明轮子!

设置:

pip install pyyaml

那么你的脚本是:

import yaml
f = open('config_file.yml')
yaml_file = yaml.safe_load(f)
for sample in yaml_file:
print yaml_file[sample]["sql"]

要运行:

python <script_name>.py

您可以将greppcregrep与以下内容一起使用:

$ while read -r line; do
echo $line
done < <(grep -oP "sql: "K.+?(?=")" config_file.yml)

输出:

select * from dbname.tableName where sampleDate>='2018-07-20';
select * from dbname.tableName where sampleDate<='2016-05-25';

在macOS中,您可以使用pcregrep -o "sql: "K.+?(?=")" config_file.yml

K可以被读取为排除它之前左边的所有内容,并且只返回右边的部分.+?(?="),直到找到"

现在,如果您的yaml更复杂,您可以尝试yq(pip install yq(,然后,例如,要获得sql值,您可以执行以下操作:

$ yq -r '.sample.sql' config_file.yml

我对脚本进行了一些修改,将键包含在一个空格分隔的列表中。

注意:此方法需要前缀。

function parse_yaml {
local prefix=$2
local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '34')
sed -ne "s|^($s):|1|" 
-e "s|^($s)($w)$s:$s["'](.*)["']$s$|1$fs2$fs3|p" 
-e "s|^($s)($w)$s:$s(.*)$s$|1$fs2$fs3|p"  $1 |
awk -F$fs '{
indent = length($1)/2;
vname[indent] = $2;
for (i in vname) {if (i > indent) {delete vname[i]}}
if (length($3) > 0) {
vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
printf("%s%s%s="%s"n", "'$prefix'",vn, $2, $3);
printf("%1$s%2$s="${%1$s%2$s} %3$s"n", "'$prefix'",vn, $2, $3);
printf("%1$s="${%1$s} %2$s"n", "'$prefix'",vn, $2, $3);
}
}'
}

使用

eval $(parse_yaml "config_file.yml" "CONF_")
# to specify all keys (apart from the final level)
for key in $CONF_; do
echo "$key"
done
# or to list keys of a specific object
for key in $CONF_sample_; do
echo "$key"
done

注:此方法仅限于核心级别和最终级别。如果其他人需要该功能,他们可能可以修改该功能以在级别之间使用。

最新更新