【问题标题】:Rename duplicate Keys in Json array data重命名 Json 数组数据中的重复键
【发布时间】:2020-07-08 14:19:59
【问题描述】:

我有一个json数据如下。

{
"Data":
[
"User": [
      {"Name": "Solomon", "Age":20}, 
      {"Name": "Absolom", "Age":30}, 
   ] 
"Country": [
       {"Name" : "US", "Resident" : "Permanent"},
       {"Name" : "UK", "Resident" : "Temporary"}
]]}

有两个标签具有相同的键, 在Users 中有Name 键,在Country 中我也有Name 键。我需要预处理 json 文件以区分密钥。我的预期结果如下。尝试通过 awk 和 sed 命令,但我找不到合适的解决方案。任何建议都会有所帮助。

预期结果:

{
"Data":
[
"User": [
      {"User_Name": "Solomon", "User_Age":20}, 
      {"User_Name": "Absolom", "User_Age":30}, 
   ] 
"Country": [
       {"Country_Name" : "US", "Country_Resident" : "Permanent"},
       {"Country_Name" : "UK", "Country_Resident" : "Temporary"}
]]}

标签名称应附加到属性名称。

这是我尝试过的,

jq '[.[] | .["User_Name"] = .Name]' file_name.json

但是UserCountry 这两个标签都会发生变化

【问题讨论】:

  • 您的示例是无效的 JSON 值。
  • 它是一个有效的 Json 文件,并且有我的数据集。
  • json数组也可以有键值对,例如w3schools.com/js/js_json_arrays.asp
  • 有人会为您提供 jq 解决方案,而在这里我可以为您提供基于 jtc 的:<file.json jtc -tc -w'<Data>l[:]<L>k<.*>L:<>k' -u'"{L}_{}";' - 这是输入不变的解决方案。 PS。我是jtc unix 工具的创建者。
  • 哦,太好了。能详细解释一下吗

标签: json key rename jq jtc


【解决方案1】:

在 OP 的许可下,这是一个基于 jtc 的解决方案,同时等待 jq(假设输入 JSON 是固定的):

bash $ <file.json jtc -w'<Data>l[:]<L>k<.*>L:<>k' -u'"{L}_{}";' -tc
{
   "Data": {
      "Country": [
         { "Country_Name": "US", "Country_Resident": "Permanent" },
         { "Country_Name": "UK", "Country_Resident": "Temporary" }
      ],
      "User": [
         { "User_Age": 20, "User_Name": "Solomon" },
         { "User_Age": 30, "User_Name": "Absolom" }
      ]
   }
}
bash $ 

jtc参数说明:

  1. -w'&lt;Data&gt;l[:]&lt;L&gt;k&lt;.*&gt;L:&lt;&gt;k'
  • 步行路径-w)选择Data标签(&lt;Data&gt;l
  • 然后是每个嵌套元素 ([:]),
  • 并将其键/标签记忆到命名空间L (&lt;L&gt;k),
  • 然后使用 REGEX 标签搜索 (&lt;.*&gt;L:)
  • 进一步查找每个标记 元素
  • 最后重新解释找到元素的键/标签作为值 (&lt;&gt;k)
  1. -u'"{L}_{}";':
  • 对于每个找到的标签(在步骤 1 中),使用模板应用更新操作 (-u)
  • "{L}_{}";',其中{L}插值,并保留在命名空间L 值中,{} 使用当前找到的标签进行插值(在 walk 路径的每次迭代中)
  • 需要尾随 ;(或任何其他符号)来区分 -u 的参数与文字 JSON。

-tc 用于以半紧凑形式显示 JSON。

PS。我是jtc unix JSON 处理工具的创建者。 SO 要求免责声明。

【讨论】:

【解决方案2】:

正如最初发布的那样,说明性输入和相应的输出都不是有效的 JSON,但以下内容已根据显示的输入使用 JSON 进行了测试:

.Data |= (  (.User    |= map(with_entries(.key |= ("User_" + .))))
          | (.Country |= map(with_entries(.key |= ("Country_" + .)))) )

当然,以上可能需要根据实际需求进行调整,并且可以通过各种方式进行概括,例如如下图。

概括

.Data |= with_entries( (.key + "_") as $newkey
                       | .value |= map(with_entries(.key |= ($newkey + .))))

【讨论】:

  • 感谢您的回答。我们可以将相同的数据转换为 csv 吗?
  • 是的,很可能使用@csv
【解决方案3】:

这里是使用 jq Streaming的方法

fromstream(tostream | .[0] |= if length < 4 then . else .[3]="\(.[1])_\(.[3])" end)

它通过使用tostream 将您的输入转换为数组流来工作

[["Data","Country",0,"Name"],"US"]
[["Data","Country",0,"Resident"],"Permanent"]
[["Data","Country",0,"Resident"]]
[["Data","Country",1,"Name"],"UK"]
[["Data","Country",1,"Resident"],"Temporary"]
[["Data","Country",1,"Resident"]]
[["Data","Country",1]]
[["Data","User",0,"Age"],20]
[["Data","User",0,"Name"],"Solomon"]
[["Data","User",0,"Name"]]
[["Data","User",1,"Age"],30]
[["Data","User",1,"Name"],"Absolom"]
[["Data","User",1,"Name"]]
[["Data","User",1]]
[["Data","User"]]
[["Data"]]

然后应用一个简单的更新赋值|= 表达式将流转换为

[["Data","Country",0,"Country_Name"],"US"]
[["Data","Country",0,"Country_Resident"],"Permanent"]
[["Data","Country",0,"Country_Resident"]]
[["Data","Country",1,"Country_Name"],"UK"]
[["Data","Country",1,"Country_Resident"],"Temporary"]
[["Data","Country",1,"Country_Resident"]]
[["Data","Country",1]]
[["Data","User",0,"User_Age"],20]
[["Data","User",0,"User_Name"],"Solomon"]
[["Data","User",0,"User_Name"]]
[["Data","User",1,"User_Age"],30]
[["Data","User",1,"User_Name"],"Absolom"]
[["Data","User",1,"User_Name"]]
[["Data","User",1]]
[["Data","User"]]
[["Data"]]

然后使用fromstream 反转转换。

Try it online!

【讨论】:

    猜你喜欢
    • 2020-05-28
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多