2015-12-14 48 views
1

將對象數組轉換爲數組對象我想使用jq將對象數組轉換爲數組對象。使用jq

考慮一下,如果我有以下兩個文件:

file1.json

{ 
    "key1": 5, 
    "key2": 10 
} 

file2.json

{ 
    "key1": 2 
} 

我想將它們合併在一起以形成:

{ 
    "key1": [5, 2] 
    "key2": [10, null] 
} 

很容易做到這一點每命令與一個字段,但我不知道如何與所有的領域一次做到這一點。我的想法是,我需要將所有值轉換爲數組,然後使用*減少,但我無法實現它的工作。

jq命令需要爲任意數量的文件(超過2個)工作。

回答

2

下面將按照您的描述將一個對象數組合併到一個對象中(特別是,null用作填充符,例如,如果每個輸入對象被視爲「觀察」,這當然是有意義的) ,但是請注意,這裏定義的merge/0不會對輸入對象中的鍵集合作任何假設,並且根據可能做出的假設,可能會使速度更快。

def merge: 
    def allkeys: map(keys) | add | unique; 
    allkeys as $allkeys 
    | reduce .[] as $in ({}; 
    reduce $allkeys[] as $k (.; 
     . + {($k): (.[$k] + [$in[$k]]) })); 

merge 

現在使用的 「啜食」 選項,如:

$ jq -s -f merge.jq file*.json 
+0

你將如何得到這個與文件任意數量的工作嗎? – schmmd

+0

@schmmd - 請注意,原始版本的merge/0不夠一般。 – peak

0

,這大概比@峯的解決方案速度較慢,但​​也許更容易閱讀:

map(to_entries) 
| flatten(1) 
| group_by(.key) 
| map({ 
    key: .[0].key, 
    value: map(.value)}) 
| from_entries 

這樣使用它:

jq -s 'map(to_entries) | flatten(1) | group_by(.key) | map({key: .[0].key, value: map(.value)}) | from_entries' file*.json 

不像你想要的outpu t,它不會將空值替換爲缺失值,如果「null」本身是一個有效值,這可能很有用。

0

這是另一種解決方案。

(add | keys) as $all             # get all keys 
| map(. as $o | reduce $all[] as $k ({}; .[$k] = $o[$k]))    # normalize objects 
| (. as $a | reduce $all[] as $k ({}; .[$k] = ($a | map(.[$k])))) # transpose 

要運行它使用-s選項,e.g:

$ jq -s -f filter.jq file1.json file2.json 

輸出示例:

{ 
    "key1": [ 
    5, 
    2 
    ], 
    "key2": [ 
    10, 
    null 
    ] 
} 

如果你有多個文件,例如file3.json

{ 
    "key3": 2 
} 

只是將它們添加到命令行

$ jq -s -f filter.jq file1.json file2.json file3.json 

輸出示例:

{ 
    "key1": [ 
    5, 
    2, 
    null 
    ], 
    "key2": [ 
    10, 
    null, 
    null 
    ], 
    "key3": [ 
    null, 
    null, 
    2 
    ] 
}