繁体   English   中英

使用python / bash缩短json对象中的键名

[英]shortening key names in a json object using python/bash

这是我编写的函数,它将更改/缩短json对象上的所有键

function replaceKeyWithNewKey(jsonObj, new_keys, old_keys){
        console.log("test")
        for(i=0;i<jsonObj.length;i++){

            for(el in jsonObj){
                //console.log(new_keys[el])
                jsonObj[i][new_keys[el]]=jsonObj[i][old_keys[el]] //add new key
                delete jsonObj[i][old_keys[el]] // delete old key
            }
        }

        return jsonObj
    }

我正在寻找的是一种在终端中使用bash或python或其他方式执行此操作的方法,但我想在终端中执行此操作。 因此,我将在file.json上运行脚本,结果将是file2.json,其中file2.json具有较短的键名。 我怎样才能做到这一点?

对于bash,我正在考虑使用sed但是我认为这不会像替换我不想替换的值那样好。 我知道的python一点点可能是要走的路。

这是控制台打印输出:

    >data[0]
    Object {Rec_Open_Date: "2016-07-07", MSISDN: 123, IMEI: 223, Data_Volume_Bytes: "673", Device_Manufacturer: "Samsung Korea"…}
    >old_keys=Object.keys(data[0])
    ["Rec_Open_Date", "MSISDN", "IMEI", "Data_Volume_Bytes", "Device_Manufacturer", "Device_Model", "Product_Description", "Data_Volume_MB"]
    >new_keys=["r", "m", "i", "d", "f", "l", "s", "d2"]
    ["r", "m", "i", "d", "f", "l", "s", "d2"]
    >function replaceKeyWithNewKey(jsonObj, new_keys, old_keys){
        console.log("test")
        for(i=0;i<jsonObj.length;i++){

            for(el in jsonObj){
                //console.log(new_keys[el])
                jsonObj[i][new_keys[el]]=jsonObj[i][old_keys[el]] //add new key
                delete jsonObj[i][old_keys[el]] // delete old key
            }
        }

        return jsonObj
    }
    undefined
    > replaceKeyWithNewKey(data, new_keys, old_keys)
    VM129:2 test
    [Objectd: "673"d2: "0.000641823"f: "Samsung Korea"i: 223l: "Samsung GT-I9505"m: 123r: "2016-07-07"s: "PREPAY PLUS - $1 - #33"__proto__: Object, Object, Object, Object, Object, Object, Object, Object, Object]

这是用于测试我的功能的示例数据:

var json = '[{"_id":"5078c3a803ff4197dc81fbfb","email":"user1@gmail.com","image":"some_image_url","name":"Name 1"},{"_id":"5078c3a803ff4197dc81fbfc","email":"user2@gmail.com","image":"some_image_url","name":"Name 2"}]';

假设您知道如何将json加载到python数据结构中。 您提供的示例数据将是dict的python list 我认为最直接的方法是建立一个将旧键映射到新键的字典,然后使用字典理解遍历列表,以从构建的键名映射中使用新的键名重建dict 使用样本:

In [8]: jobj = [{"_id":"5078c3a803ff4197dc81fbfb","email":"user1@gmail.com","image":"some_image_url","name":"Name 1"},{"_id":"5078c3a803ff4197dc81fbfc","email":"user2@gmail.com","image":"some_image_url","name":"Name 2"}]

In [9]: keymap = {'email':'e', 'image':'img', 'name':'n', '_id':'id'}

In [10]: for i in range(len(jobj)):
     ...:     jobj[i] = {keymap[k]:jobj[i][k] for k in jobj[i]}
     ...: 

In [11]: jobj
Out[11]: 
[{'e': 'user1@gmail.com',
  'id': '5078c3a803ff4197dc81fbfb',
  'img': 'some_image_url',
  'n': 'Name 1'},
 {'e': 'user2@gmail.com',
  'id': '5078c3a803ff4197dc81fbfc',
  'img': 'some_image_url',
  'n': 'Name 2'}]

编辑添加

如果要确保所有键都保持顺序,则需要使用collections OrderedDict

import json
from collections import OrderedDict

keymap = {'email':'e', 'image':'img', 'name':'n', '_id':'id'}

with open('ordered_example.json') as f:
    jobj = json.load(f, object_pairs_hook=OrderedDict)


for i in range(len(jobj)):
    jobj[i] = OrderedDict((keymap[k],jobj[i][k]) for k in jobj[i])

print(jobj)

输出:

[OrderedDict([('id', '5078c3a803ff4197dc81fbfb'),
              ('e', 'user1@gmail.com'),
              ('img', 'some_image_url'),
              ('n', 'Name 1')]),
 OrderedDict([('id', '5078c3a803ff4197dc81fbfc'),
              ('e', 'user2@gmail.com'),
              ('img', 'some_image_url'),
              ('n', 'Name 2')])]

如果要从命令行处理JSON ,建议安装jq

您可以将键映射放置在bash 4+中的关联数组中,如下所示:

declare -A map=([foobar]=foo [poohbah]=pooh [zoowicky]=zoo)

并循环遍历以构建一个jq脚本来替换密钥。

jq_script=
for old in "${!map[@]}"; do
  new="${map[$old]}"
  jq_script+="${jq_script:+|}if has(\"$old\") then { \"$new\": .[\"$old\"] } + del(.[\"$old\"]) else . end"
done

您可以这样运行:

jq "$jq_script" <old.json >new.json

在我的示例JSON上:

{
  "foobar": 1,
  "zoowicky": 3,
  "different": 4
}

它在地图中没有所有键,并且在地图中没有键,它会产生以下结果:

{
  "zoo": 3,
  "foo": 1,
  "different": 4
}

仅使用sed替代键。

#!/bin/bash

function replaceKeyWithNewKey() {

    json_file="$1"
    old_key="$2"
    new_key="$3"

    # you'd better to backup first.
    sed -i "" "s/${old_key}/${new_key}/g" ${json_file}
}

old_keys=("Rec_Open_Date" "MSISDN" "IMEI" "Data_Volume_Bytes" "Device_Manufacturer" "Device_Model" "Product_Description" "Data_Volume_MB")

new_keys=("r" "m" "i" "d" "f" "l" "s" "d2")

# input json file
json_file="input"

for ((i = 0; i < ${#old_keys[@]}; ++i)) do
    replaceKeyWithNewKey ${json_file} "${old_keys[$i]}" "${new_keys[$i]}"
done

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM