Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jq get each value in array with parent

Tags:

json

jq

I have json that looks like the below. I'd like to get an output that contains one line for each timer record, but includes the name of the service.

{  
   "services":{  
      "service":[  
         {  
            "name":"Test Value",
            "timer":[  
               { "datetime":"08/30/2017 16:33:35", "value":"625" },
               { "datetime":"08/30/2017 16:22:38", "value":"240" }
            ]
         },
         {
            "name":"Test Value 2",
            "timer":[
               { "datetime":"08/30/2017 16:07:38", "value":"432" },
               { "datetime":"08/30/2017 15:59:07", "value":"1355" }
            ]
         }
      ]
   }
}

I've come up with .services.service[].name as $name | .services.service[].timer | map([ $name, .datetime, .value ]), which gets me

[["Test Value","08/30/2017 16:33:35","625"],["Test Value","08/30/2017 16:22:38","240"]]
[["Test Value","08/30/2017 16:07:38","432"],["Test Value","08/30/2017 15:59:07","1355"]]
[["Test Value 2","08/30/2017 16:33:35","625"],["Test Value 2","08/30/2017 16:22:38","240"]]
[["Test Value 2","08/30/2017 16:07:38","432"],["Test Value 2","08/30/2017 15:59:07","1355"]]

The output that I'm expecting would be

[["Test Value","08/30/2017 16:33:35","625"],["Test Value","08/30/2017 16:22:38","240"]]
[["Test Value 2","08/30/2017 16:07:38","432"],["Test Value 2","08/30/2017 15:59:07","1355"]]

But notice that the values are duplicated for both services and sets of timers. What am I missing?

like image 229
Glen Solsberry Avatar asked Aug 31 '17 13:08

Glen Solsberry


1 Answers

.services.service[]|[{name,timer:.timer[]}|[.name,.timer[]]] will give you your expected output,

.services.service[]|{name,timer:.timer[]}|[.name,.timer[]] (without array aggregation) will give you one result for each timer:

["Test Value","08/30/2017 16:33:35","625"]
["Test Value","08/30/2017 16:22:38","240"]
["Test Value 2","08/30/2017 16:07:38","432"]
["Test Value 2","08/30/2017 15:59:07","1355"]

What you missed in your attempt is

The expression exp as $x | ... means: for each value of expression exp, run the rest of the pipeline with the entire original input, and with $x set to that value. Thus as functions as something of a foreach loop.

If you really want to use variables you need to do it like this: .services.service[]| .name as $name | .timer | map([ $name, .datetime, .value ])

like image 130
Michał Politowski Avatar answered Oct 19 '22 06:10

Michał Politowski