解析具有不同数量 key:values 的 yaml 文件
Parse yaml file with varying number of key:values
长话短说,我将使用 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 循环遍历每个文件并将变量设置为值
例如:
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}
顺序无关紧要,我只需要能够说明可能出现在需要添加到 'add client' 命令的 yaml 中的其他字段。 yaml 中的每一行都将添加到命令中。添加的每个键都将成为 'add client' 命令的可行参数。我不必担心 yaml 中的键是否是有效参数。他们会的。
对这里未知的最佳方法感到好奇。谢谢!
如果找不到密钥,我假设 yq returns 什么都没有。
我可能会根据 yq returns 来制作整个标志,例如
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
如果您只运行 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
阅读本文时的一些注意事项:
- bash中的每个
read
命令读取一行,当-d
不用于修改时
- 上面的
yq
命令输出每个数据项一行。
- 使用
// ""
会导致在未找到 CLIENT_MIDDLE_NAME
时使用空字符串,而不是 null
。
${foo:+...words here...}
扩展为 ...words here...
当且仅当 foo
设置为非空值时。
长话短说,我将使用 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 循环遍历每个文件并将变量设置为值 例如:
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}
顺序无关紧要,我只需要能够说明可能出现在需要添加到 'add client' 命令的 yaml 中的其他字段。 yaml 中的每一行都将添加到命令中。添加的每个键都将成为 'add client' 命令的可行参数。我不必担心 yaml 中的键是否是有效参数。他们会的。
对这里未知的最佳方法感到好奇。谢谢!
如果找不到密钥,我假设 yq returns 什么都没有。
我可能会根据 yq returns 来制作整个标志,例如
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
如果您只运行 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
阅读本文时的一些注意事项:
- bash中的每个
read
命令读取一行,当-d
不用于修改时 - 上面的
yq
命令输出每个数据项一行。 - 使用
// ""
会导致在未找到CLIENT_MIDDLE_NAME
时使用空字符串,而不是null
。 ${foo:+...words here...}
扩展为...words here...
当且仅当foo
设置为非空值时。