如何从bash中的yaml文件中删除特定密钥

时间:2019-05-24 12:50:05

标签: bash key yaml

我正在尝试从YAML文件中删除1个如下所示的密钥:

users:
  - aaa
  - bbb

roles:
  - aaa
  - bbb
  - ccc

我正在寻找一种方法,仅删除此users.aaa而无需触摸roles.aaa,以便输出为:

users:
  - bbb

roles:
  - aaa
  - bbb
  - ccc

有什么想法吗?如果可以通过某些标准工具完成该操作,而无需安装任何其他命令,那就太好了。

我一直在尝试使用以下示例: How to remove a child block from YML in shell script? 但这没用。我不是awk大师。

2 个答案:

答案 0 :(得分:0)

如果您可以根据描述来格式化输入(请注意,映射和序列都有替代的YAML语法),则可以使用sed

sed -i -e '/^users:/,/^[^ ]*:/!n;/[ ]\{1,\}-[ ]\{1,\}aaa/d' my_file.yaml

该sed表达式有点复杂,所以让我们对其进行分解。有两个命令,用分号(;)隔开:

  • /^users:/,/^[^ ]*:/!n

    这是下一行(!)命令的取反(n)地址范围。这会导致所有与地址范围不匹配的行都原样传递给输出。唯一需要进一步处理的行是那些以正则表达式/^users:/匹配的行开始,一直到正则表达式/^[^ ]*:/匹配的下一条后续行的行范围内的行。换句话说,users键本身,与该键关联的值的元素以及(无害地)下一个键本身。

  • /[ ]\{1,\}-[ ]\{1,\}aaa/d

    通过第一个命令的过滤器的那些行都受此约束,该行与提供的正则表达式要查找的sequence元素匹配,并将其(d)从输出中删除。这是最后一条命令,因此此处未删除的行将传递到输出。

答案 1 :(得分:0)

awk脚本的不错挑战。我会尝试以下脚本:

awk '/^[[:alpha:]]+:/ {level1=$0; next} level1 ~ "users" && /aaa/ {next} 1' input.yml