我正在寻找一种简单的UNIX方法,用于将使用shell脚本获取的数据保存到YAML文件中,例如,我想使用shell管道将系统中已安装的软件包列表(rpms,pypi)保存在单个YAML文件中,像:
rpm -qa |排序| some-yaml-tool manifest.yaml system.packages
预期结果将是manifest.yaml
文件,如下所示:
system:
packages:
- xz-5.2.2-2.fc24.x86_64
- xz-devel-5.2.2-2.fc24.x86_64
虽然我更喜欢YAML,但我不会拒绝兼容JSON的解决方案。我真的很想找到一种方法来使用大多数发行版上提供的工具,而不是需要手动安装或从非官方yum / deb存储库安装的东西。
如果该工具是智能工具,它应该能够在存在时创建文件和内部路径。
请注意,我必须从列表中删除jq
工具,因为它not allow in-place editing。
答案 0 :(得分:1)
您根本不需要就预期用例提供就地编辑支持。注意到YAML是JSON的超集,因此jq
的所有输出也是有效的YAML:
rpm -qa | sort | jq -Rn '{"system": {"packages": [inputs]}}'
将生成以下格式的输出文件:
{
"system": {
"packages": [
"bar",
"baz",
"foo"
]
}
}
......只需一次通过。为了使这个更加惯用的YAML,您可以使用PyYAML库解析一个小的Python垫片:
yaml_format() {
python -c 'import sys, yaml; sys.stdout.write(yaml.dump(yaml.load(sys.stdin), default_flow_style=False))'
}
rpm -qa | sort | jq -Rn '{"system": {"packages": [inputs]}}' | yaml_format
...将生成以下形式的内容:
system:
packages:
- bar
- baz
- foo
我们假设您已经拥有一个JSON文件,其内容不是您要保留的清单。在这种情况下,明确提出的问题变得相关。安全(尽管仅限GNU)实现如下所示:
atomic_update() {
# usage: atomic_update filename command arg1 arg2 ...
local filename tempfile retval=0
filename=$1; shift || return
tempfile=$(mktemp -t -- "$filename.XXXXXX") || return
if "$@" <"$filename" >"$tempfile"; then
# Make a best-effort attempt to preserve permissions
chown --reference="$filename" -- "$tempfile" &>/dev/null ||:
chmod --reference="$filename" -- "$tempfile" &>/dev/null ||:
mv -- "$tempfile" "$filename"
else
retval=$?
rm -f -- "$tempfile"
fi
return "$retval"
}
rpm -qa | sort | atomic_update manifest.yml jq -Rn '.system.packages = [inputs]'
答案 1 :(得分:0)
虽然我还没有完全正常工作的解决方案,但我认为我非常接近通过json
npm包找到一个。
echo "{}" > e.json
seq 3 | xargs -0 -I XXX json -I -f e.json -e 'this.numbers=XXX'
cat e.json
现在唯一缺少的部分是关于如何使用列表并合并它而不是覆盖值。