2014-08-28 55 views
15

我有以下JSON數據:如何使用jq將我的JSON轉換爲CSV?

{"id":"111","case":"Y","custom":{"speech invoked":"no","input method":"hard","session ID":"420"}} 

我怎樣才能將其轉換爲使用jq所以我的結果看起來是這樣的CSV格式?

id,case,session Id,speech invoked,input method 

111,Y,420,no,hard 

我嘗試以下,但它沒有工作:

{(.id),(.case),(.custom."session Id"),(.custom."speech invoked"),(.custom."input method")} 

如果沒有任何可能的Perl或外殼的解決方案表示讚賞。

回答

-1

使用Perl和JSON模塊:

#!/usr/bin/perl 
use warnings; 
use strict; 
use feature qw{ say }; 

use JSON; 

my $input = << '__JSON__'; 
{"id":"111","case":"Y","custom":{"speech invoked":"no","input method":"hard","session ID":"420"}} 
__JSON__ 

my $struct = decode_json($input); 

my @header = grep ! ref $struct->{$_}, keys %$struct; 
push @header, map keys %{ $struct->{$_} }, 
       grep ref $struct->{$_}, 
       keys %$struct; 

my @row = grep ! ref, values %$struct; 
push @row, map values %$_, grep ref, values %$struct; 

say join ',', @header; 
say join ',', @row; 
+0

我還是想用文字:: CSV_XS創建輸出以防萬一的一些數據包括像空格,引號,逗號等。 – Tanktalus 2014-08-29 04:46:22

+0

@Tanktalus:當然。只需調整最後兩行。 – choroba 2014-08-29 07:22:50

+1

這不會像問題那樣使用'jq'。 – reinierpost 2016-05-30 08:58:12

16

使用perl是不是一個很好的解決方案,我反而有點試驗和錯誤我想通了之後,你可以只用jq使用join()運營商做。

首先製作你需要的輸出數組,然後用逗號連接數組元素。

jq -r '[.case, .custom."speech invoked", .custom."input method"] | join(", ")' 

享受。 :)

+0

我放棄了'.custom。「會話ID」',這樣人們就可以在不滾動的情況下看到join()。 – 2014-11-07 21:31:09

+1

謝謝喬,這對其他人很有幫助。 – user2711819 2014-11-10 18:47:33

11

使用JQ,您可以使用此過濾器:

with_entries(select(.key != "custom")) + .custom 
    | to_entries 
    | map(.key), map(.value) 
    | @csv 

只是注意,這樣寫的,「自定義」屬性將永遠寫在最後,不管性質是按什麼順序。在喬·哈里斯的回答

+1

這很酷,因爲它在事先不知道它們的情況下自動獲取密鑰,並輸出列標題。但問題是每個行的標題都會重複*。如果你有變量輸入,你可以安全地輸出值,但是如果輸入是可變的,你需要頭文件。首先將輸入和輸出標題保存到文件中,然後在第二遍中添加值。雖然會阻止將輸出傳輸到gzip。 – 2016-02-09 16:46:51

16

大廈,您可以使用@csv過濾器,使字符串被正確引用和轉義必要時:

jq -r '[.case, .custom."speech invoked", .custom."input method"] | @csv' 
+0

酷!很好的發現。 – 2015-07-07 15:30:01

+0

看起來比連接好,但始終圍繞值生成雙引號。 – eventhorizon 2017-11-24 10:27:24

1

這裏是另一種解決方案。如果data.json包含樣本數據,則

jq -M -s -r 'map(.+.custom|del(.custom)) | (.[0]|keys_unsorted), (.[]|[.[]]) | join(",")' data.json 

會產生

id,case,speech invoked,input method,session ID 
111,Y,no,hard,420