在一行中的某些字段中格式化某些JSON对象吗?

时间:2019-11-06 18:56:17

标签: python json jq pretty-print

我想重新格式化JSON文件,以使带有某些特定键的某些对象(字典)在一行上。

例如,任何具有键name的对象都应显示在一行中:

{
  "this": "that",
  "parameters": [
    { "name": "param1", "type": "string" },
    { "name": "param2" },
    { "name": "param3", "default": "@someValue" }
  ]
}

已生成JSON文件,其中包含编程语言数据。单行的某些字段使直观检查/查看变得更加容易。

我尝试重写python json.JSONEncoder,以在写入之前将匹配的dict变成string,只是意识到字符串中的引号"再次在结果JSON中转义文件,打败了我的目的。

我也看过jq,但找不到解决方法。我根据行长发现了类似的问题和解决方案,但我的要求更简单,并且我不希望更改其他较短的行。仅某些对象或字段。

1 个答案:

答案 0 :(得分:3)

此代码用唯一字符串(UUID)递归替换数据中所有适当的dict,并记录这些替换,然后在缩进的JSON字符串中,将唯一的字符串替换为所需的原始单行JSON。

replace返回一对:

  • 输入自变量数据的修改版本
  • 成对的JSON字符串对列表,其中每对JSON字符串都应在最终的漂亮印刷JSON中用第二个值替换。
import json
import uuid


def replace(o):
    if isinstance(o, dict):
        if "name" in o:
            replacement = uuid.uuid4().hex
            return replacement, [(f'"{replacement}"', json.dumps(o))]
        replacements = []
        result = {}
        for key, value in o.items():
            new_value, value_replacements = replace(value)
            result[key] = new_value
            replacements.extend(value_replacements)
        return result, replacements
    elif isinstance(o, list):
        replacements = []
        result = []
        for value in o:
            new_value, value_replacements = replace(value)
            result.append(new_value)
            replacements.extend(value_replacements)
        return result, replacements
    else:
        return o, []


def pretty(data):
    data, replacements = replace(data)
    result = json.dumps(data, indent=4)
    for old, new in replacements:
        result = result.replace(old, new)
    return result


print(pretty({
    "this": "that",
    "parameters": [
        {"name": "param1", "type": "string"},
        {"name": "param2"},
        {"name": "param3", "default": "@someValue"}
    ]
}))