2015-05-28 2 views
1

Мне нужно изменить JSON-файл с помощью python. Когда я впервые работаю с python (и JSON), я прочитал некоторые статьи об этом, но не понял его полностью.Добавить «запись» в файл JSON с Python

Мне удалось импортировать JSON в python, как какой-то массив (или список?).

JSON выглядит следующим образом:

{ 
    "sources":[{ 
    "id":100012630, 
    "name":"Activity Login Page", 
    "category":"NAM/Activity", 
    "automaticDateParsing":true, 
    "multilineProcessingEnabled":false, 
    "useAutolineMatching":false, 
    "forceTimeZone":true, 
    "timeZone":"Europe/Brussels", 
    "filters":[], 
    "cutoffTimestamp":1414364400000, 
    "encoding":"UTF-8", 
    "pathExpression":"C:\\NamLogs\\nam-login-page.log*", 
    "blacklist":[], 
    "sourceType":"LocalFile", 
    "alive":true 
    },{ 
    "id":100001824, 
    "name":"localWinEvent", 
    "category":"NAM/OS/EventLog", 
    "automaticDateParsing":true, 
    "multilineProcessingEnabled":false, 
    "useAutolineMatching":false, 
    "forceTimeZone":false, 
    "filters":[], 
    "cutoffTimestamp":1409090400000, 
    "encoding":"UTF-8", 
    "logNames":["Security","Application","System","Others"], 
    "sourceType":"LocalWindowsEventLog", 
    "alive":true 
    },{ 
    "id":100001830, 
    "name":"localWinPerf", 
    "category":"NAM/OS/Perf", 
    "automaticDateParsing":false, 
    "multilineProcessingEnabled":false, 
    "useAutolineMatching":false, 
    "forceTimeZone":false, 
    "filters":[], 
    "cutoffTimestamp":0, 
    "encoding":"UTF-8", 
    "interval":60000, 
    "wmiQueries":[{ 
     "name":"NAMID Service", 
     "query":"SELECT * FROM Win32_PerfRawData_PerfProc_Process WHERE Name = 'tomcat7'" 
    },{ 
     "name":"CPU", 
     "query":"select * from Win32_PerfFormattedData_PerfOS_Processor" 
    },{ 
     "name":"Logical Disk", 
     "query":"select * from Win32_PerfFormattedData_PerfDisk_LogicalDisk" 
    },{ 
     "name":"Physical Disk", 
     "query":"select * from Win32_PerfFormattedData_PerfDisk_PhysicalDisk" 
    },{ 
     "name":"Memory", 
     "query":"select * from Win32_PerfFormattedData_PerfOS_Memory" 
    },{ 
     "name":"Network", 
     "query":"select * from Win32_PerfFormattedData_Tcpip_NetworkInterface" 
    }], 
    "sourceType":"LocalWindowsPerfMon", 
    "alive":true 
    }, 

Теперь, когда я получил сотни файлов, как те, что я написал Еогеасп через весь каталог:

for filename in os.listdir('./json/'): 
    with open('./json/'+filename) as data_file:  
    sources = json.load(data_file) 

Теперь мне нужно что-то вроде снова источник foreach в источниках, который добавляет строку (или запись или что-то вроде «строки» в JSON) для каждого источника (что-то вроде collectorName = имя_файла), а затем перезаписывает старый файл новым.

JSON будет выглядеть следующим образом:

{ 
     "sources":[{ 
     "id":100012630, 
     "name":"Activity Login Page", 
     "category":"NAM/Activity", 
     "automaticDateParsing":true, 
     "multilineProcessingEnabled":false, 
     "useAutolineMatching":false, 
     "forceTimeZone":true, 
     "timeZone":"Europe/Brussels", 
     "filters":[], 
     "cutoffTimestamp":1414364400000, 
     "encoding":"UTF-8", 
     "pathExpression":"C:\\NamLogs\\nam-login-page.log*", 
     "blacklist":[], 
     "sourceType":"LocalFile", 
     "alive":true, 
     "collectorName":"Collector2910" 
     },{ 
     "id":100001824, 
     "name":"localWinEvent", 
     "category":"NAM/OS/EventLog", 
     "automaticDateParsing":true, 
     "multilineProcessingEnabled":false, 
     "useAutolineMatching":false, 
     "forceTimeZone":false, 
     "filters":[], 
     "cutoffTimestamp":1409090400000, 
     "encoding":"UTF-8", 
     "logNames":["Security","Application","System","Others"], 
     "sourceType":"LocalWindowsEventLog", 
     "alive":true, 
     "collectorName":"Collector2910" 
     },{..... 

Я надеюсь, что я мог бы объяснить мою проблему, и я был бы рад, если кто-то может мне помочь (даже с совершенно иным решением).

Заранее спасибо

Майкл

ответ

2

Вот один из способов сделать это:

for filename in os.listdir('./json/'): 
    sources = None 
    with open('./json/'+filename) as data_file:  
     sources = json.load(data_file) 
     sourcelist = sources['sources'] 
     for i, s in enumerate(sourcelist): 
      sources['sources'][i]['collectorName'] = 'Collector' + str(i) 
    with open('./json/'+filename, 'w') as data_file: 
     data_file.write(json.dumps(sources)) 
+0

почему 'источники [ 'источники'] [я]', когда у вас есть запись доступной как 's'? И почему 'data_file.write (json.dumps (sources))' когда у вас есть 'json.dump (obj, file)'? –

+0

1) Я предпочитаю не изменять список, через который я выполняю итерацию. 2) Они эквивалентны, метод json.dump делает почти то же самое. – chown

+0

1. Изменение списка, который вы выполняете, опасно только при добавлении/удалении элементов из этого списка, а не при изменении элементов, уже находящихся в списке, - и в текущем случае источники источников '] [i] is s == True' - на самом деле оба названия указывают на один и тот же объект. 2. да, но второй меньше кода для написания;) –

1
for filename in os.listdir('./json/'): 
    with open('./json/'+filename) as data_file:  
     datadict = json.load(data_file) 
    # At this point you have a plain python dict. 
    # This dict has a 'sources' key, pointing to 
    # a list of dicts. What you want is to add 
    # a 'collectorName': filename key:value pair 
    # to each of these dicts 
    for record in datadict["sources"]: 
     record["collectorName"] = filename 
    # now you just have to serialize your datadict back 
    # to json and write it back to the file - which is 
    # in fact a single operation 
    with open('./json/'+filename, "w") as data_file:  
     json.dump(datadict, data_file) 
+0

также в этом попытаюсь выполнить: ValueError: объект JSON не может быть декодирован – Michael

+0

это проблема с json.loads и json.load? – Michael

+0

oh дерьмо .... .DS_Store также пытается открыть как JSON .... – Michael