我正在尝试从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大师。
答案 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