使用 shell 解析 YAML 部分

使用 shell 解析 YAML 部分

我的 YAML 看起来像

something:
 - whatever:
   - something
 - toc: 4
 - body: assets/footer.html
pkg:
 - pkg_a_1:
   - Shass
   - AJh55
   - ASH7
 - pkg_b_1:
   - Kjs6
   - opsaa
other:
morestuff:
 - whatever

我想提取下面的内容包装并将它们打印到文本文件中,如下所示:

pkg_a_1 Shass
pkg_a_1 AJh55
pkg_a_1 ASH7
pkg_b_1 Kjs6
pkg_b_1 opsaa

我试图避免使用完整的 YAML 解析器,因为我只需要这一节,而不需要大型 YAML 文件中的其他内容。

  • 部分标签 (包装) 是固定的,只出现一次并且不会改变。
  • 小节标签和小节数量 (pkg_a_1,pkg_b_1) 可以换。
  • 每个小节下的项目数量和顺序可以更改。项目只能包含[A-Za-z0-9]+.
  • 前后内容包装部分可以更改。 IE;各部分某物:其他:可能存在也可能不存在。

答案1

$ awk '/^[^ ]/{ f=/^pkg:/; next } f{ if (sub(/:$/,"")) pkg=$2; else print pkg, $2 }' file
pkg_a_1 Shass
pkg_a_1 AJh55
pkg_a_1 ASH7
pkg_b_1 Kjs6
pkg_b_1 opsaa

答案2

使用yq来自https://kislyuk.github.io/yq/

yq -r '.pkg[] | to_entries[] | .key as $key | .value[] | [ $key, . ] | @tsv' file.yaml

这会将 YAML 数据转换为 JSON 文档,该文档yq能够使用jq表达式进行处理。

该表达式将 的条目转换pkg为一组对象,如下所示:

{
  "key": "pkg_a_1",
  "value": [
    "Shass",
    "AJh55",
    "ASH7"
  ]
}
{
  "key": "pkg_b_1",
  "value": [
    "Kjs6",
    "opsaa"
  ]
}

每个此类对象的value数组都会被迭代,并且key当前的数组value将使用运算符转换为制表符分隔的列表@tsv

考虑到问题中的数据,最终输出是制表符分隔的列表

pkg_a_1 Shass
pkg_a_1 AJh55
pkg_a_1 ASH7
pkg_b_1 Kjs6
pkg_b_1 opsaa

答案3

你也可以选择迈克法拉的yq, 和jq

yq -j r infile.yml 'pkg.*' |
jq -r 'to_entries[] | .key as $k | .value | map(. = $k + " " + .) | join("\n")'

输出:

pkg_a_1 Shass
pkg_a_1 AJh55
pkg_a_1 ASH7
pkg_b_1 Kjs6
pkg_b_1 opsaa

相关内容