Json

使用 JQ 展平 JSON 線數組

  • June 13, 2021

我可以寫

> echo '{"a": "arbiter", "b": "brisk"}{"a": "astound", "b": "bistro"}' | jq '.a, .b'
"arbiter"
"brisk"
"astound"
"bistro"

但如果我這樣做

> echo '{"a": "arbiter", "b": "brisk", "c": ["cloak", "conceal"]} {"a": "astound", "b": "bistro", "c": ["confer", "consider"]}' | jq '.a, .b, .c'

我明白了

"arbiter"
"brisk"
[
   "cloak",
   "conceal"
]
"astound"
"bistro"
[
   "confer",
   "consider"
]

我如何展平c陣列來代替

"arbiter"
"brisk"
"cloak",
"conceal"
"astound"
"bistro"
"confer",
"consider"

更新

由於空安全在幾種現代語言中非常流行(並且有理由這樣做),因此假設上面提出的問題不完整可能是合適的。有必要知道如何處理缺少值。

如果其中一個值為null

> echo '{"b": "brisk"}{"a": "astound", "b": "bistro"}' | jq '.a, .b'

我們在輸出中得到一個空值

null
"brisk"
"astound"
"bistro"

這很可能就是我們想要的。我們可以在管道中添加第二步(注意不要 exclude "null"),但如果jq它本身排除nulls 會更乾淨。只是寫作select(.a != null)就可以了,但會引入一個{}級別。null從內部丟棄 s的正確方法是什麼jq

jq表達式_

[.a, .b, .c]

從輸入對像中提取我們想要的所有元素,並將它們放在一個數組中。其中一些元素可能是數組,因此我們需要展平所有元素:

[.a, .b, .c] | flatten

對於輸入對象

{
 "a": "arbiter",
 "b": "brisk",
 "c": [
   "cloak",
   "conceal"
 ]
}

這會生成數組

[
 "arbiter",
 "brisk",
 "cloak",
 "conceal"
]

你會從你的第二個對像中得到一個類似但獨立的數組。

要將這兩個數組合併為一個,我們可以簡單地通過 傳遞數據.[],但一種快捷的寫法flatten | .[]flatten[]。使用它,我們到達

[.a, .b, .c] | flatten[]

概括:

echo '...as in the question...' |
jq '[.a, .b, .c] | flatten[]'

如果您還想清除任何null值,請過濾select(. != null)或使用 提取值[.a//empty,.b//empty,.c//emtpy],或過濾map(.//empty)before flatten[]


作為評論:您的輸入 JSON 是使用echo問題中的簡單內容創建的。但是,要在命令行上正確創建 JSON,請考慮使用類似的工具jo,它會另外對您的數據進行適當的編碼以包含在 JSON 文件中:

您的第二個範例 JSON 可以使用兩個jo呼叫創建

jo a=arbiter b=brisk  'c[]'=cloak  'c[]'=conceal
jo a=astound b=bistro 'c[]'=confer 'c[]'=consider

引用自:https://unix.stackexchange.com/questions/654014