【问题标题】:Rename JSON key after a specific pattern在特定模式后重命名 JSON 键
【发布时间】:2021-07-21 15:06:15
【问题描述】:

我有一个包含以下内容的 JSON 对象:

{
    "quiz": {
        "sport": {
            "id": "77",
            "q1": {
                "question": "Which one is correct team name in NBA?",
                "options": [
                    "New York Bulls",
                    "Huston Rocket"
                ],
                "answer": "Huston Rocket"
            }
        },
        "maths": {
            "q1": {
                "question": "5 + 7 = ?",
                "options": [
                    "10",
                    "13"
                ],
                "answer": "13"
            },
        }
    }
}

并且我想查找 KEY“id”。一旦找到,就开始寻找KEY“answer”并将其重命名为“answer_id”。

预期输出:

{
    "quiz": {
        "sport": {
            "id": "77",
            "q1": {
                "question": "Which one is correct team name in NBA?",
                "options": [
                    "New York Bulls",
                    "Huston Rocket"
                ],
                "answer_id": "Huston Rocket"
            }
        },
        "maths": {
            "q1": {
                "question": "5 + 7 = ?",
                "options": [
                    "10",
                    "13"
                ],
                "answer": "12"
            },
           
        }
    }
}

到目前为止,我已经尝试过,但没有正确捕捉到该字段:

awk   ' { for ( i = 1; i <= NF; ++i ) {

              if ( $i == "id" )
                  r = 1

              if ( r && $i == "answer")
                  $i = "answer_id" 
                  r = 0           
            }
          }
          1 ' example.json > example2.json

【问题讨论】:

  • 嗨!如果我会给你一个使用 python 解决这个问题的方法。对你有帮助吗?
  • 是的! @AndreiGurko
  • 我刚刚发布了我的解决方案。请尝试一下))
  • 是否总是有一个问题,即q1,还是会有多个问题?
  • q1会有倍数。我的意思是这是结构,但键会出现不止一次

标签: python awk sed


【解决方案1】:

这里,解决方案之一...

data = {
    "quiz": {
        "sport": {
            "id": "77",
            "q1": {
                "question": "Which one is correct team name in NBA?",
                "options": [
                    "New York Bulls",
                    "Huston Rocket"
                ],
                "answer": "Huston Rocket"
            }
        },
        "maths": {
            "q1": {
                "question": "5 + 7 = ?",
                "options": [
                    "10",
                    "13"
                ],
                "answer": "13"
            },
        }
    }
}

for key in data.get('quiz'):
    inner_data = data['quiz'][key]
    if 'id' in inner_data and 'answer' in inner_data['q1']:
        inner_data['q1']['answer_id'] = inner_data['q1'].pop('answer')

print(data)

【讨论】:

  • 是否有任何选项可以保留原始订单?
  • @Max 对不起,我不明白你。你的意思是如何保存 inner_data['q1'].pop('answer') 的值还是别的什么?
  • 我的意思是当我在虚拟机中执行我的代码时,它首先给我的是“数学”而不是“运动”
  • @Max,我想解释一下。所以 data 是一个 dict 结构,并且 dict 不保证键将始终用于当前位置。但是从python3.7我读到,dict保证键的顺序。
  • 你如何将标签'quiz'重命名为'data1'
【解决方案2】:

保留密钥顺序的 jq 解决方案:

walk(if type=="object" and .id
  then walk(if type=="object" and .answer 
    then  with_entries(if .key=="answer"
      then .key+="_id" else . end)
    else . end)
  else . end)

或者也许你想要:

walk(if type=="object" and .id
  then .id |= walk(if type=="object" and .answer 
    then  with_entries(if .key=="answer"
      then .key+="_id" else . end)
    else . end)
  else . end)

【讨论】:

  • 你能解释一下吗?
  • @Max - 考虑 {"id": 0, "answer": 1}
  • 对不起,我不明白。你在用jq吗?
  • @Max - 请看你Q的第一行,我的A的第一行。
【解决方案3】:

这是针对同一 JSON 查询的基于 jtc 的解决方案(假设源 JSON 在 file.json 中):

bash $ <file.json jtc -w'<id>l:[-1]<answer>l:<>k' -u'"answer_id"'

就这么简单。

PS。碰巧我是jtc 的开发人员 - 适用于 unix 的 JSON 多线程处理工具
聚苯乙烯。上述免责声明是 SO 的要求

【讨论】:

  • 这对我的情况无效。 jq有什么想法吗?提前致谢
  • @Max, jq 解决方案由 peak 提供
猜你喜欢
  • 1970-01-01
  • 2014-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-26
  • 2011-12-13
  • 1970-01-01
  • 2016-03-18
相关资源
最近更新 更多