![](/img/trans.png)
[英]jq - remove non-matching fields in "object-array-with-objects"
[英]Remove matching/non-matching elements of a nested array using jq
我需要將sonarqube分析歷史記錄的結果拆分為單個文件。 假設下面有一個開始輸入,
{
"paging": {
"pageIndex": 1,
"pageSize": 100,
"total": 3
},
"measures": [
{
"metric": "coverage",
"history": [
{
"date": "2018-11-18T12:37:08+0000",
"value": "100.0"
},
{
"date": "2018-11-21T12:22:39+0000",
"value": "100.0"
},
{
"date": "2018-11-21T13:09:02+0000",
"value": "100.0"
}
]
},
{
"metric": "bugs",
"history": [
{
"date": "2018-11-18T12:37:08+0000",
"value": "0"
},
{
"date": "2018-11-21T12:22:39+0000",
"value": "0"
},
{
"date": "2018-11-21T13:09:02+0000",
"value": "0"
}
]
},
{
"metric": "vulnerabilities",
"history": [
{
"date": "2018-11-18T12:37:08+0000",
"value": "0"
},
{
"date": "2018-11-21T12:22:39+0000",
"value": "0"
},
{
"date": "2018-11-21T13:09:02+0000",
"value": "0"
}
]
}
]
}
如何使用jq清除結果,以便它只保留每個元素的歷史數組條目? 所需的輸出是這樣的(輸出20181118123808.json用於“2018-11-18T12:37:08 + 0000”的分析):
{
"paging": {
"pageIndex": 1,
"pageSize": 100,
"total": 3
},
"measures": [
{
"metric": "coverage",
"history": [
{
"date": "2018-11-18T12:37:08+0000",
"value": "100.0"
}
]
},
{
"metric": "bugs",
"history": [
{
"date": "2018-11-18T12:37:08+0000",
"value": "0"
}
]
},
{
"metric": "vulnerabilities",
"history": [
{
"date": "2018-11-18T12:37:08+0000",
"value": "0"
}
]
}
]
}
我迷失了如何僅在子元素上操作同時保持父結構完整。 JSON文件的命名將從jq實用程序外部處理。 提供的樣本數據將分為3個文件。 其他一些輸入可以有可變數量的條目,有些可能高達10000.謝謝。
這是一個使用awk
編寫不同文件的解決方案。 該解決方案假定每個度量的日期相同且順序相同,但對不同日期的數量或不同度量的數量沒有限制。
jq -c 'range(0; .measures[0].history|length) as $i
| (.measures[0].history[$i].date|gsub("[^0-9]";"")), # basis of filename
reduce range(0; .measures|length) as $j (.;
.measures[$j].history |= [.[$i]])' input.json |
awk -F\\t 'fn {print >> fn; fn="";next}{fn="output-" $1 ".json"}'
awk
的選擇只是為了方便。
這種方法的缺點是,如果要對每個文件進行整齊格式化,則每個文件都需要額外運行漂亮的打印機(例如jq)。 因此,如果要求每個文件中的輸出都是整潔的,則可以為每個日期運行jq一次,從而避免了對后處理( awk
)步驟的需要。
如果措施的日期不是鎖定步驟,那么仍然可以使用與上述相同的方法,但當然,收集日期和相應的措施必須以不同方式進行。
上面調用jq產生的前兩行如下:
"201811181237080000"
{"paging":{"pageIndex":1,"pageSize":100,"total":3},"measures":[{"metric":"coverage","history":[{"date":"2018-11-18T12:37:08+0000","value":"100.0"}]},{"metric":"bugs","history":[{"date":"2018-11-18T12:37:08+0000","value":"0"}]},{"metric":"vulnerabilities","history":[{"date":"2018-11-18T12:37:08+0000","value":"0"}]}]}
在評論中,出現了原始問題的以下附錄:
是否存在一種變化,其中過濾是基於日期值而不是位置? 不能保證訂單是相同的,或者每個度量中的元素數量將是相同的(即一些日期可能缺少“錯誤”,一些可能具有額外的度量,例如“復雜性”)。
以下將生成一個JSON對象流,每個日期一個。 此流可以使用我之前的答案中的日期進行注釋,該日期顯示如何使用這些注釋來創建各種文件。 為了便於理解,我們使用了兩個輔助函數:
def dates:
INDEX(.measures[].history[].date; .)
| keys;
def gather($date): map(select(.date==$date));
dates[] as $date
| .measures |= map( .history |= gather($date) )
如果你的jq沒有INDEX/2
,那么現在是升級的絕佳時機,但是如果不可行的話,這就是它的def:
def INDEX(stream; idx_expr):
reduce stream as $row ({};
.[$row|idx_expr|
if type != "string" then tojson
else .
end] |= $row);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.