2016-07-15 21 views
0

這是我寫的,這將改變/縮短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"}]'; 
+1

既然你已經w ritten代碼在JavaScript中執行此操作,爲什麼不堅持? (爲什麼要切換語言?) – smarx

+0

這與sed(標記爲)有什麼關係? –

+0

@smarx,因爲我想要它在文件格式。而js我已經格式化了一部分,也許我只需要從文件中寫入文件並寫入文件部分,然後再練習如何在終端或其他方式中執行此操作。如果你能簡單地解釋,想知道如何做到這一點。 – HattrickNZ

回答

1

假設你知道如何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'}] 

編輯添加的

如果你想確保所有的鑰匙留在順序,您需要從使用OrderedDictcollections

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')])] 
+0

tks,無論如何保持'jobj'的順序與'keymap'相同? – HattrickNZ

+1

@HattrickNZ是的,你需要使用'OrderedDict's。看我的編輯。 –

+0

tks,我喜歡你添加你的編輯的方式,並沒有覆蓋你最初的帖子! – HattrickNZ

0

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 
+0

如果您想備份,請不要將空參數傳遞給'sed -i'。 – tripleee

+0

每次更換舊鍵的功能都會備份..所以不能只用這個來備份原來的文件。 –

1

如果你將要操縱在命令行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 
}