使用不同数量的key:value解析yaml文件

时间:2020-04-28 17:58:12

标签: bash yaml sh yq

长话短说,我将使用yq使用bash解析目录中的yaml文件。我的Yaml文件可能如下所示:

CLIENT_FIRST_NAME: bob
CLIENT_LAST_NAME: smith

CLIENT_FIRST_NAME: bob
CLIENT_LAST_NAME: smith
CLIENT_MIDDLE_NAME: michael

所以我用do循环遍历每个文件,并将变量设置为value 例如:

for f in $FILES
do
  FIRSTNAME=$(yq r $f CLIENT_FIRST_NAME)
  LASTNAME=$(yq r $f CLIENT_LAST_NAME)
add client --firstname=${FIRSTNAME} --lastname=${LASTNAME}
done

但是有时候我会有这个中间名,并且我需要包括它:

add client --firstname=${FIRSTNAME} --lastname=${LASTNAME} --middlename=${MIDDLENAME}

顺序无关紧要,我只需要能够说明yaml中可能需要添加到“添加客户端”命令中的其他字段。 yaml中的每一行都将添加到命令中。添加的每个密钥将是“添加客户端”命令的可行参数。我不必担心yaml中的键是否为有效参数。他们会的。

对未知的最佳方法感到好奇。谢谢!

2 个答案:

答案 0 :(得分:1)

我假设yq如果找不到键,则不返回任何内容。

我可能会根据yq是否返回某些内容来制作整个标记,例如

for f in "${FILES[@]}"
do
  FIRSTNAME=$(yq r "$f" CLIENT_FIRST_NAME)
  MIDDLENAME=$(yq r "$f" CLIENT_MIDDLE_NAME)
  LASTNAME=$(yq r "$f" CLIENT_LAST_NAME)

  [[ -n $MIDDLENAME ]] && MIDDLENAME="--middlename=${MIDDLENAME}"
add client --firstname="${FIRSTNAME}" --lastname="${LASTNAME}" "${MIDDLENAME}"
done

答案 1 :(得分:1)

如果您仅对每个输入文件运行yq 一次,而不对每个输入文件每个数据项一次,则此代码将更加高效。考虑:

for f in *.yml; do
  { read -r firstname; read -r middlename; read -r lastname; } < <(
    yq -r '(.CLIENT_FIRST_NAME, .CLIENT_MIDDLE_NAME // "", .CLIENT_LAST_NAME)' "$f"
  )
  add client \
    --firstname="$firstname" \
    ${middlename:+--middlename="$middlename"} \
    --lastname="$lastname"
done

在阅读本文时需要注意的一些事项:

  • 当不使用read进行修改时,bash中的每个-d命令都会读取一行。
  • 上面的yq命令每个数据项输出一行。
  • 使用// ""会导致在找不到null时使用空字符串而不是CLIENT_MIDDLE_NAME
  • 如果仅将${foo:+...words here...}设置为非空值,
  • ...words here...会扩展为foo