我們正在接收來自客戶的資料并且它是高度嵌套的(客戶這樣做是為了減少重復資料的數量,從而減少傳輸資料的整體大小)。
資料如下所示:
{
"r1": "ex",
"r2": "of",
"r3": "da",
"ver": 1,
"noa1": [{
"col1": 380,
"noa2": [{
"aon": [123],
"obj": {
"col10": "stuf",
"col11": "here",
"aos": ["A",
"X"
]
}
}, {
"aon": [],
"obj": {
"col10": "more",
"col11": "stuf"
}
}, {
"aon": [456, 789]
}, {
"obj": {
"col10": "anon"
}
}]
}, {
"col1": 5676,
"noa2": [{
"aon": [875],
"obj": {
"col10": "does",
"col11": "noth",
"aos": ["Y",
"Z"
]
}
}, {
"obj": {
"col11": "phew"
}
}]
}]
}
其中有許多可選的嵌套物件和陣列(大約 6 級深 IRL,但在此處進行了簡化)。
我們必須將其展平為 CSV,其中每一行都是唯一的,其中包含 JSON 物件的資料。我們不希望從跨積連接創建任何“新行”。所以上面看起來像:
r1|r2|r3|ver|col1|aon|col10|col11|aos
ex|of|da|1 |380 |123|stuf |here |A
ex|of|da|1 |380 |123|stuf |here |X
ex|of|da|1 |380 | |more |stuf |
ex|of|da|1 |380 |456| | |
ex|of|da|1 |380 |789| | |
ex|of|da|1 |380 | | anon| |
ex|of|da|1 |5676|875|does |noth |Y
ex|of|da|1 |5676|875|does |noth |Z
ex|of|da|1 |5676| | |phew |
For brevity, we show this as a table. In reality, we would want this to be a collection of JSON documents (jq -c).
我們一直在使用 jq,但在使用不是物件的嵌套陣列時遇到了困難,比如字串陣列。它導致發生交叉連接,將值放在原始 JSON 中不存在的位置。我們也遇到了可選嵌套行的問題(如果陣列為空,jq 當前不會列印該行,即使使用 ? 修飾符也是如此。
問題是:
- 原始 JSON 的 jq 過濾器是什么?
- 一般來說,如何處理 jq 中的嵌套物件、陣列以及字串、數字等陣列?
更新:以下代碼
.r1 as $r1 | .r2 as $r2 | .r3 as $r3 | .ver as $ver | .noa1[] | . as $noa1 | .noa2[] | . as $noa2 | {$r1, $r2, $r3, $ver, "col1": $noa1.col1, "aon": $noa2.aon }
回傳
{"r1":"ex","r2":"of","r3":"da","ver":1,"col1":380,"aon":[123]}
{"r1":"ex","r2":"of","r3":"da","ver":1,"col1":380,"aon":[]}
{"r1":"ex","r2":"of","r3":"da","ver":1,"col1":380,"aon":[456,789]}
{"r1":"ex","r2":"of","r3":"da","ver":1,"col1":380,"aon":null}
{"r1":"ex","r2":"of","r3":"da","ver":1,"col1":5676,"aon":[875]}
{"r1":"ex","r2":"of","r3":"da","ver":1,"col1":5676,"aon":null}
這是有道理的。但是現在,當我們嘗試更進一步并分解“aon”數字陣列時,它變得很奇怪。這段代碼
.r1 as $r1 | .r2 as $r2 | .r3 as $r3 | .ver as $ver | .noa1[] | . as $noa1 | .noa2[] | . as $noa2 |
{$r1, $r2, $r3, $ver, "col1": $noa1.col1, "aon": $noa2.aon[]? }
丟失具有“aon”空值的行,我可以理解,有點(因為?)。但是這段代碼失敗了
.r1 as $r1 | .r2 as $r2 | .r3 as $r3 | .ver as $ver | .noa1[] | . as $noa1 | .noa2[] | . as $noa2 |
{$r1, $r2, $r3, $ver, "col1": $noa1.col1, "aon": $noa2.aon[] }
我也明白,因為空值。所以我們嘗試將它作為一個變數來參考:
.r1 as $r1
| .r2 as $r2
| .r3 as $r3
| .ver as $ver
| .noa1[] | . as $noa1
| .noa2[] | . as $noa2
| .obj as $obj
| .aon[]? | . as $aon
| {$r1, $r2, $r3, $ver, "col1": $noa1.col1, "aon": $aon, "col10": $obj.col10, "col11": $obj.col11 }
并走到這一步。但是有幾個問題:我們丟失了一些 aon 為空的行,我們不知道如何訪問“aos”。
uj5u.com熱心網友回復:
我不確定您是否希望“aos”欄位出現在每個生成的物件中。如果沒有,您可能會做得比:
jq -c '
.r1 as $r1
| .r2 as $r2
| .r3 as $r3
| .ver as $ver
| .noa1[]
| .col1 as $col1
| .noa2[]
| .aon as $aon
| .obj
| {$r1, $r2, $ver, $col1, $aon, col10, col11}
try {aos: .aos[]} catch {} '
如果你這樣做,那么你可以將最后一個替換為{}或{aos: null}其他。如果您不想使用,try ... catch那么您可以用一個if陳述句替換它,或者可以用:
( (.aos // [null]) | {aos: .[]} )
我認為,保持理智的關鍵是避免創建 jq 變數,除非“深入”時需要。此外,jq 對 {$x} 和 {y} 等縮寫的支持使事情更容易閱讀和審查。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/521129.html
標籤:jsonUnixjq
上一篇:替換部分fasta標頭
下一篇:不懂Linux命令
