如何使用jq将一个复杂的json数据转换成csv

flvtvl50  于 2023-07-31  发布在  其他
关注(0)|答案(2)|浏览(119)

我是新来的,在使用jq工具。我从mongodb数据库中提取了一个json文件,并将其格式化为csv:

foo.json中的json数据

{
    "_id" : "8888888888",
    "unitcode" : "Unit123",
    "purpose" : "Validate",
    "request" : {
        "url" : "Brocolli",
        "method" : "UPDATED",
        "body" : {
            "bonds" : [
                {
                    "bondDesc" : "bondDesc1",
                    "priorPriceBid" : 100,
                    "priorPriceOffer" : 101,
                    "priorYieldBid" : 6.555,
                    "priorYieldOffer" : 6.777,
                    "updatedPriceBid" : 691,
                    "updatedPriceOffer" : 169,
                    "updatedYieldBid" : 25.2345,
                    "updatedYieldOffer" : 25.9999
                },
                {
                    "bondDesc" : "bondDesc2",
                    "priorPriceBid" : 200,
                    "priorPriceOffer" : 201,
                    "priorYieldBid" : 2.555,
                    "priorYieldOffer" : 2.777,
                    "updatedPriceBid" : 791,
                    "updatedPriceOffer" : 269,
                    "updatedYieldBid" : 35.2345,
                    "updatedYieldOffer" : 35.9999
                }
            ]
        },
        "source" : "Cloud",
        "isMultipleBond" : true
    },
    "response" : {
        "statusCode" : 200
    }
}

字符串

期望输出:

"UPDATED","Brocolli","bondDesc1",100,101,6.555,6.777,691,169,25.2345,25.9999
"UPDATED","Brocolli","bondDesc2",200,201,2.555,2.777,791,269,35.2345,35.9999

我已经尝试了以下命令:

1.初次尝试

jq -r '[.request.method, .request.url] | @csv'  foo.json

结果:

"bondDesc1",100


1.下次尝试

jq -r ' .request.body.bonds[] | [.bondDesc, .priorPriceBid, .priorPriceOffer, .priorYieldBid, .priorYieldOffer, .updatedPriceBid, .updatedPriceOffer, .updatedYieldBid, .updatedYieldOffer] | @csv' foo.json

结果:

"bondDesc1",100,101,6.555,6.777,691,169,25.2345,25.9999
"bondDesc2",200,201,2.555,2.777,791,269,35.2345,35.9999


1.但我不知道如何将它们组合起来,它只是给了我一个错误:

jq -r ' [.request.method, .request.url], .request.body.bonds[] | [.bondDesc, .priorPriceBid, .priorPriceOffer, .priorYieldBid, .priorYieldOffer, .updatedPriceBid, .updatedPriceOffer, .updatedYieldBid, .updatedYieldOffer] | @csv' foo.json

结果:

jq: error (at foo.json:40): Cannot index array with string "bondDesc"

gajydyqb

gajydyqb1#

由于所需的字段位于不同的深度和数组中,因此典型的策略是在每个级别收集所需的值,分别展开任何数组,然后将它们全部合并。
假设您希望值按文件顺序排列,则可以从焊接对象中获取所有值。

.request | [.method, .url] + (.body.bonds[] | [.[]]) | @csv

字符串
尽管一般来说,您可能希望明确地挑选出所需的值。

.request | [.method, .url] + (.body.bonds[] | [
  .bondDesc,
  .priorPriceBid,
  .priorPriceOffer,
  .priorYieldBid,
  .priorYieldOffer,
  .updatedPriceBid,
  .updatedPriceOffer,
  .updatedYieldBid,
  .updatedYieldOffer
]) | @csv


您的想法是正确的,但是bonds数组展开式周围的圆括号很重要。
jqplay

vsmadaxz

vsmadaxz2#

正如@Jeff_Mercado提到的,您可能会使用

.request | [.method, .url] + (.body.bonds[] | [.[]]) | @csv

字符串
但是这假设对象内的键的顺序是相同的。即使您认为是这种情况,采用更健壮的解决方案也是明智的。列出键是一种方法,但这很乏味,而且对于w.r. t来说不健壮。将来添加或删除密钥。
假设您想要与第一个.bonds对象中的键对应的所有值,您可以使用以下命令:

.request
| (.body.bonds[0] | keys_unsorted) as $keys
| [.method, .url] + (.body.bonds[] | [.[$keys[]]])
| @csv

相关问题