簡體   English   中英

如何使用jq從json創建具有可變數組長度的csv

[英]How to make a csv from json with variable array lengths using jq

我有一個具有以下格式的JSON

{
    "type": "conversation",
    "id": "1234",
    "created_at": 1425586662,
    "initial_message": {
        "type": "initial_message",
        "id": "567",
        "body": "<p>Testing</p>",
        "author": {
            "type": "admin",
            "id": "9382"
        }
    },
    "conversation_parts": {
        "type": "conversation_part.list",
        "conversation_parts": [
            {
                "type": "conversation_part",
                "id": "6789",
                "part_type": "comment",
                "body": "<p>Good test</p>",
                "created_at": 1425586731,
                "author": {
                    "type": "user",
                    "id": "029384"
                }
            },
            {
                "type": "conversation_part",
                "id": "9384",
                "part_type": "close",
                "body": null,
                "created_at": 1425929944,
                "author": {
                    "type": "admin",
                    "id": "9382"
            }
        ]
    }
}

總是有一個initial_message,但是會話部分數組中可能有也可能沒有任何內容,並且該數組可能有任意數量的成員。

我試圖在csv中捕獲一些這些信息,雖然我對@csv函數沒有運氣

我試過了:

jq '"\(.type), \(.id), \(.created_at), \(.initial_message.type), \(.initial_message.id), \(.initial_message.author.type), \(.conversation_parts.conversation_parts[].part), \(.conversation_parts.conversation_parts[].id), \(.conversation_parts.conversation_parts[].part_type), \(.conversation_parts.conversation_parts[].created_at), \(.conversation_parts.conversation_parts[].author.type)"' \

但是它給了我所有可能的數組內部組合(我從這個例子得到32行結果)。

我正在編輯我正在尋找的信息總量,但我的理想是顯示

1234, 567, initial, admin
1234, 6789, comment, user
1234, 9384, close, admin

如果可以的話我會沒事的

1234, 567, admin, 6789, comment, user
1234, 567, admin, 9384, close, admin

我不能擁有的是

1234, 567, admin, 6789, comment, user
1234, 567, admin, 9384, comment, admin
1234, 567, admin, 6789, close, user
1234, 567, admin, 9384, close, admin

這就是我現在要得到的

我知道在jq和foreach函數中有一個長度函數,但是后來我在管道中糾結了如何遍歷對話部分的數組。 任何幫助將非常感激!

jq中,如果您有一個數組,例如

[1,2,3]

那么使用[]數組迭代的字符串插值對象構造過濾器將生成多個字符串或對象,例如

$ jq -Mnc '[1,2,3] | {x:.[]}'
{"x":1}
{"x":2}
{"x":3}

$ jq -Mnc '[1,2,3] | "x:\(.[])"'
"x:1"
"x:2"
"x:3"

如果存在多個[] ,則將產生組合的笛卡爾積。 例如

$ jq -Mnc '[1,2,3] | "x:\(.[]) x:\(.[])"'
"x:1 x:1"
"x:2 x:1"
"x:3 x:1"
"x:1 x:2"
"x:2 x:2"
"x:3 x:2"
"x:1 x:3"
"x:2 x:3"
"x:3 x:3"

如果這不是您想要的,避免它的一種簡單方法是將[]移出插值,例如

$ jq -Mnc '[1,2,3] | .[] | "x:\(.) x:\(.)"'
"x:1 x:1"
"x:2 x:2"
"x:3 x:3"

同樣,在使用嵌套結構時, 變量綁定通常很有用。 例如

$ jq -Mnc '{a:100, b:[1,2,3]} | .a as $a | .b[] | "a:\($a) b:\(.)"'
"a:100 b:1"
"a:100 b:2"
"a:100 b:3"

最后,這里有一個使用這些功能來解決這個問題的過濾器。 函數用於保持處理初始消息和會話部分的邏輯分離。

def initial:
    .id as $id
  | .initial_message
  |   .type as $ity
  |   .id   as $iid
  |   .author
  |     .type as $iaty
  |     "\($id), \($iid), \($ity), \($iaty)"
;

def parts:
    .id as $id
  | .conversation_parts.conversation_parts[]  # note [] here
  |   .id as $cid
  |   .part_type as $cpt
  |   .author
  |     .type as $caty
  |     "\($id), \($cid), \($cpt), \($caty)"
;

  initial
, parts

如果filter.jq包含此過濾器,而data.json包含樣本數據,則

$ jq -M -r -f filter.jq data.json

會產生

1234, 567, initial_message, admin
1234, 6789, comment, user
1234, 9384, close, admin

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM