2017-05-26 118 views
0

我編寫了一個循環當前Jsonfile的小腳本,但無法附加鍵和值。更改和更新JSON文件

這是我的文件

[ 
    { 
    "URL": "https://p59-caldav.icloud.com", 
    } 
] 

我想追加這樣

[ 
    { 
    "URL": "https://p59-caldav.icloud.com", 
    "test": "test" 
    } 
] 

鍵和值我目前的腳本設置

#!/usr/bin/env ruby 

require 'rubygems' 
require 'json' 
require 'domainatrix' 

jsonHash = File.read("/Users/ReffasCode/Desktop/sampleData.json") 
array = JSON.parse(jsonHash) 

File.open("/Users/BilalReffas/Desktop/sampleData.json","w") do |f| 

    array.each do |child| 
    url = Domainatrix.parse(child["URL"]) 
    json = { 
     "url" => child["URL"], 
     "provider" => url.domain, 
     "service" => url.subdomain, 
     "context" => url.path, 
     "suffix" => url.public_suffix 
    } 

    f.write(JSON.pretty_generate(json)) 
    end 
end 

劇本改寫了我的整個jsonfile ...這不是我想要的:/

+0

你真的需要在這裏修改縮進,因爲我認爲你對循環內部和內部什麼都感到困惑。 – tadman

+0

你必須覆蓋原文。您無法輕鬆安全地追加,插入或修改磁盤上的JSON(或通常的文本文件)。 –

回答

2

這是未經測試,但看起來大約右:

ORIGINAL_JSON = 'sampleData.json' 
NEW_JSON = ORIGINAL_JSON + '.new' 
OLD_JSON = ORIGINAL_JSON + '.old' 

json = JSON.parse(File.read(ORIGINAL_JSON)) 

ary = json.map do |child| 
    url = Domainatrix.parse(child['URL']) 
    { 
    'url' => child['URL'], 
    'provider' => url.domain, 
    'service' => url.subdomain, 
    'context' => url.path, 
    'suffix' => url.public_suffix 
    } 
end 

File.write(NEW_JSON, ary.to_json) 

File.rename(ORIGINAL_JSON, OLD_JSON) 
File.rename(NEW_JSON, ORIGINAL_JSON) 
File.delete(OLD_JSON) 

不覆蓋原來的文件,直到發生所有的處理,因此寫入到一個新的文件,關閉新與舊,然後重命名是很重要的舊的安全的,重新命名爲原來的名稱,然後能夠刪除原來的。如果您沒有遵循這樣的流程,那麼如果代碼或機器中途崩潰,您將面臨破壞或丟失原始數據的風險。

有關更多信息,請參閱「How to search file text for a pattern and replace it with a given value」。

+0

File.mv不存在,您需要使用FileUtils.mv並需要'fileutils' – BilalReffas

+0

或者,使用它們的File的版本。 –

1

可能最簡單的使用f.write的方法是使用它來替換文件的全部內容。考慮到這一點,讓我們看看我們是否可以將文件的全部內容都放在內存中,然後編寫它。

#!/usr/bin/env ruby 

require 'rubygems' 
require 'json' 
require 'domainatrix' 

write_array = [] 
jsonHash = File.read("/Users/ReffasCode/Desktop/sampleData.json") 
read_array = JSON.parse(jsonHash) 
read_array.each do |child| 
    url = Domainatrix.parse(child["URL"]) 
    write_array << { 
     "url" => child["URL"], 
     "provider" => url.domain, 
     "service" => url.subdomain, 
     "context" => url.path, 
     "suffix" => url.public_suffix 
    } 
end 

File.open("/Users/BilalReffas/Desktop/sampleData.json","w") do |f| 
    f.write(JSON.pretty_generate(write_array)) 
end 

注意一些變化:

  1. 固定縮進:)
  2. 與文件的全部內容去掉了一些嵌套
  3. 寫一次。除非你有一個非常重要的文件或對流水線I/O非常重要的需求,否則這可能是最簡單的事情。
+0

最後一節可以更容易地寫成'File.write(「/ Users/BilalRefas/Desktop/sampleData.json」,JSON.pretty_generate(write_array))'。 –