【发布时间】:2022-01-06 09:04:11
【问题描述】:
上下文:我有一个场景,我需要将备份从一个系统复制到另一个系统。我希望备份列表是可配置的,所以我在脚本本身中使用了 JSON 方法。
该列表包含密钥(要在输出中显示的备份名称)、用于 ssh 的用户以及从中获取备份的路径。
例子:
backups_to_perform='[
{
"key": "key1",
"user": "user1",
"path": "path1"
},
{
"key": "key2",
"user": "user2",
"path": "path2"
},
{
"key": "key3",
"user": "user3",
"path": "path3"
},
]'
我使用 JSON 的原因是我希望有一个类似于 python 字典的结构,因为关联数组只能有key:pair,而不是key{key:pair; key:pair}(如果我错了,请纠正我)
这就是我解析 JSON 的方式:
while read -r backup; do
IFS=, read -r key user path <<<"$(jq -cr '"\(.key),\(.user),\(.path)"' <<<"$backup")"
rsync_backup "$key" "$user" "$path"
done < <(jq -cr '.[]' <<<"$backups_to_perform")
rsync_backup 只是一个执行 rsync 的函数,它接受这些参数。
可能有更好的解决方案来实现我想要的备份副本,但我想改进这种类型的代码,以便下次更好地应用它。
我的问题是,当 JSON 很大时,这似乎需要一些时间(我已经为这篇文章减少了 3 个)。看起来我解析 JSON 的方式非常复杂,但我无法让它以任何其他方式工作。
我调用jq 一次来提供循环,然后在每次迭代中再次调用它可能很糟糕。
【问题讨论】:
-
我会使用 csv 文件和 GNU Parallel
parallel --csv没有 jq 并且由于并行执行而更快。我相信你也可以将 csv 转换为 python dict。 -
我会切换到具有 JSON 解析器的语言,而不是使用
jq来尝试生成bash可以处理的更简单的输入格式。 -
@chepner 如果只是提供一个可以用 bash 解析的输出,那么 jq 就足够了,不是吗?
-
“字典”就是某些语言所称的关联数组。在 JSON 中,它们被称为“对象”。
-
@Fravadona 仅假设您对存储在对象中的值有足够的了解,以了解构造 CSV 或 TSV 值是否安全。问题是没有适当的数据结构可以将值从
jq传递到bash,只有字符串。使用不需要依赖此类字符串编码的语言将值从一个函数传递到另一个更简单。
标签: arrays json bash performance jq