使用shell迭代yaml

klr1opcd  于 2023-06-24  发布在  Shell
关注(0)|答案(3)|浏览(115)

我有一个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 @ '\034')
sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|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

我无法理解我如何能够迭代通过这一点。

gcxthw6b

gcxthw6b1#

为什么你不能使用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
9wbgstp7

9wbgstp72#

您可以使用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更复杂,你可以给予yqpip install yq),然后,例如,要获得sql的值,你可以这样做:

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

kyvafyod3#

我对脚本做了一点修改,将键包含在一个空格分隔的列表中。
注意:此方法需要前缀。

function parse_yaml {
  local prefix=$2
  local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
  sed -ne "s|^\($s\):|\1|" \
    -e "s|^\($s\)\($w\)$s:$s[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p" \
    -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|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

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

相关问题