2017-04-04 49 views
1

嗨我正在嘗試在單個「jq」命令中執行一個計算,但我無法制定如何引用新值。JSON和jq更新多個值

原始JSON

{ 
    "Status": "Down", 
    "StatusID": "75328241", 
    "Start": "2017-03-17 15:06:40", 
    "End": "2017-03-17 15:08:37", 
    "Period": "1 Minutes " 
} 

我的目標是在開始和結束時間轉換爲時代和鍛鍊的時間以秒計。然後用新值輸出相同的對象。

當我這樣做

echo $J_SON | jq '.Start |= (strptime("%Y-%m-%d %H:%M:%S") | mktime),.End |= (strptime("%Y-%m-%d %H:%M:%S") | mktime)' 

輸出是:

{ 
    "Status": "Down", 
    "StatusID": "75328241", 
    "Start": 1489763200, 
    "End": "2017-03-17 15:08:37", 
    "Period": "1 Minutes " 
} 
{ 
    "Status": "Down", 
    "StatusID": "75328241", 
    "Start": "2017-03-17 15:06:40", 
    "End": 1489763317, 
    "Period": "1 Minutes " 
} 

這是有道理的,手冊上說,這是默認行爲。

jq中的分配工作與大多數編程 語言有些不同。 jq不區分 的引用和副本 - 兩個對象或數組相等或不相等, 沒有任何進一步的概念,即「同一對象」或「不相同的 對象」。

如果一個對象有兩個字段其陣列,包含.foo和的.bar,你 附加的東西包含.foo,那麼的.bar不會得到更大的,即使 您之前設置的.bar =包含.foo 。如果您習慣於使用Python,Java,Ruby,Javascript等語言編程 ,那麼您可以認爲它是 ,就像jq在執行任務之前完成每個對象的完整深層副本實際上這樣做,但這是一般的想法)。

但是,我會然後想輸出在時代以及秒的值。

我設法成功地得到這樣的持續時間:

echo $J_SON | jq '.Period = ((.End | strptime("%Y-%m-%d %H:%M:%S") | mktime)-(.Start | strptime("%Y-%m-%d %H:%M:%S") | mktime))' 

輸出

{ 
    "Status": "Down", 
    "StatusID": "75328241", 
    "Start": "2017-03-17 15:06:40", 
    "End": "2017-03-17 15:08:37", 
    "Period": 117 
} 

問題:

我可以得到每個變量的各個值,但不確定如何在單個輸出對象中連接它們。

回答

2

你可以鏈在一起的更新,像這樣:

.Start |= (strptime("%Y-%m-%d %H:%M:%S") | mktime) 
| .End |= (strptime("%Y-%m-%d %H:%M:%S") | mktime) 
| .Period = (.End - .Start) 
+0

謝謝,非常完美。我不明白的是「過濾器分離器」。如果它只對特定值的子對象起作用,那你爲什麼要在管道上使用它。我想在閱讀數值和動態更改時使用它是有道理的,在這種情況下,您不需要管道。 – Arturski