使用python/bash的
这是我写的,这将改变/缩短JSON对象上的所有按键的功能在一个JSON对象,缩短按键的名称使用python/bash的
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":"[email protected]","image":"some_image_url","name":"Name 1"},{"_id":"5078c3a803ff4197dc81fbfc","email":"[email protected]","image":"some_image_url","name":"Name 2"}]';
假设你知道如何JSON的加载到一个Python数据结构。您提供的样本数据将是dict
s的Python list
。我认为最直接的方法是构建一个将旧密钥映射到新密钥的字典,然后使用字典解析遍历列表,以便使用您创建的密钥名称映射中的新密钥名称重建dict
。使用您的样本:
In [8]: jobj = [{"_id":"5078c3a803ff4197dc81fbfb","email":"[email protected]","image":"some_image_url","name":"Name 1"},{"_id":"5078c3a803ff4197dc81fbfc","email":"[email protected]","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': '[email protected]',
'id': '5078c3a803ff4197dc81fbfb',
'img': 'some_image_url',
'n': 'Name 1'},
{'e': '[email protected]',
'id': '5078c3a803ff4197dc81fbfc',
'img': 'some_image_url',
'n': 'Name 2'}]
编辑添加的
如果你想确保所有的钥匙留在顺序,您需要从使用OrderedDict
collections
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', '[email protected]'),
('img', 'some_image_url'),
('n', 'Name 1')]),
OrderedDict([('id', '5078c3a803ff4197dc81fbfc'),
('e', '[email protected]'),
('img', 'some_image_url'),
('n', 'Name 2')])]
tks,无论如何保持'jobj'的顺序与'keymap'相同? – HattrickNZ
@HattrickNZ是的,你需要使用'OrderedDict's。看我的编辑。 –
tks,我喜欢你添加你的编辑的方式,并没有覆盖你最初的帖子! – HattrickNZ
Just使用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
如果您想备份,请不要将空参数传递给'sed -i'。 – tripleee
每次更换旧键的功能都会备份..所以不能只用这个来备份原来的文件。 –
如果你将要操纵在命令行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
}
既然你已经w ritten代码在JavaScript中执行此操作,为什么不坚持? (为什么要切换语言?) – smarx
这与sed(标记为)有什么关系? –
@smarx,因为我想要它在文件格式。而js我已经格式化了一部分,也许我只需要从文件中写入文件并写入文件部分,然后再练习如何在终端或其他方式中执行此操作。如果你能简单地解释,想知道如何做到这一点。 – HattrickNZ