在特定模式后重命名 JSON 键

Posted

技术标签:

【中文标题】在特定模式后重命名 JSON 键【英文标题】:Rename JSON key after a specific pattern 【发布时间】: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会有倍数。我的意思是这是结构,但键会出现不止一次 【参考方案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 提供

以上是关于在特定模式后重命名 JSON 键的主要内容,如果未能解决你的问题,请参考以下文章

php递归键重命名仅用于内部数组

如何在 Scala/Spark 中为数据框中的每一行编写一个 Json 文件并重命名文件

在文件作为 RandomAccessFile 打开并映射为 MappedByteBuffer 后重命名文件

在 cbind 数据后重命名列名

在 PySpark 中将数据帧写入 CSV 后重命名文件 [重复]

将数据导出到 csv 并在计算机配置文件名称后重命名