与字符串键混合的漂亮打印有效 JSON

时间:2021-04-26 08:22:39

标签: json bash redis jq

我有一个带有键和值的 Redis 哈希,比如字符串键——序列化的 JSON 值。 相应的 rediscli 查询 (hgetall some_redis_hash) 被转储到一个文件中:

redis_key1
{"value1__key1": "value1__value1", "value1__key2": "value1__value2" ...}
redis_key2
{"value2__key1": "value2__value1", "value2__key2": "value2__value2" ...}
...
and so on.

所以问题是,我如何漂亮地打印括号中的这些值? (请注意,如果您尝试解析整个文档,则它们之间的关键字符串会使文档无效) 第一个想法是从 Redis 中获取特定对,剥离寄生键,并在剩余的有效 JSON 上使用 jq,如下所示:

rediscli hget some_redis_hash redis_key1 > file && tail -n +2 file
- file now contains valid JSON as value, the first string representing Redis key is stripped by tail -
cat file | jq
- produces pretty-printed value -

所以问题是,如何在没有这种预处理的情况下进行漂亮的打印? 或者(在这种特殊情况下会更好)如何在一个大的 JSON 中合并键和值,其中可在上层访问的 Redis 键将跟随其值的字典? 像这样:

rediscli hgetall some_redis_hash > file
cat file | cool_parser
- prints { "redis_key1": {"value1__key1": "value1__value1", ...}, "redis_key2": ... }

1 个答案:

答案 0 :(得分:2)

一种简单的漂亮打印方法如下:

cat file | jq --raw-input --raw-output '. as $raw | try fromjson catch $raw'

它尝试将每一行解析为带有 fromjson 的 json,如果不能,则仅输出原始行(带有 $raw)。

(存在 --raw-input 以便我们可以调用包含在 fromjson 中的 try 而不是直接在每一行上运行它,并且 --raw-output 存在以便任何非 json 行不在输出中用引号括起来。)


仅使用 jq 解决问题的第二部分:

cat file \
    | jq --raw-input --null-input '[inputs] | _nwise(2) | {(.[0]): .[1] | fromjson}' \
    | jq --null-input '[inputs] | add'
  • --null-input 结合 [inputs] 将整个输入生成为一个数组
  • 然后将 _nwise(2) 分成两个 (more info on _nwise) 的组
  • {(.[0]): .[1] | fromjson} 然后转换为 json 列表
  • 然后将 | jq --null-input '[inputs] | add' 组合成单个 json

或者在单个 jq 调用中:

cat file | jq --raw-input --null-input \
    '[ [inputs] | _nwise(2) | {(.[0]): .[1] | fromjson} ] | add'

...但到那时,您最好编写一个更容易理解的 Python 脚本。