Home > Software design >  collecting objects into array doesn't work
collecting objects into array doesn't work

Time:01-08

I have an input file of JSON objects (log file from an application):

{ 
  "Url": "http://bla-bla/method1",
  "ReturnCode": 200,
  ...
}
{ 
  "Url": "http://bla-bla/method2",
  "ReturnCode": 500,
  ...
}

etc.

I manipulate it through a number of transformation in jq (such as select, regex functions, etc.) and in the end I shape the final object

| { UserName, Url, Duration }

But I want to collect (as jq calls it) this stream into an array in order to group_by. All the examples I see start with array, and then have | [.[] | { UserName, Url, Duration }], which works. However, if I just specify [{ UserName, Url, Duration }], I don't get a single array; instead I get

[
  { 
  "UserName": "John",
  "Url": "http://bla-bla/method1",
  "Duration ": 10
  }
]
[
  { 
  "UserName": "Bob",
  "Url": "http://bla-bla/method2",
  "Duration": 15
  }
]

Doesn't make any sense!

Note - I know that I can use jq "my rules" | jq -s and it works. But there should be a way to create an array inside the rules themselves!

CodePudding user response:

Everything in jq is a filter. Even an innocuous value like 1 is a filter: it ignores its input and produces the number 1 as output.

[...] is a filter, too. For each value in its input, it applies the enclosed filter to that value and collects the output into a single array.

This means that the only way to create a single array as output is to take a single value as input. If jq's input is a stream of values, jq '[...] will produces a stream of outputs. In order to convert a stream of values into a single array, you need to use the -s option first.

CodePudding user response:

As you start off with a stream of objects, you may either use the --slurp (or -s) flag to read in the objects as array members (you don't have to use another call, just begin with jq -s '<your filter, maybe using a map>'), or use inputs in conjunction with the --null-input (or -n) flag, which lets you construct the array more flexibly: jq -n '[inputs] | …' or even jq -n '[inputs | …]', depending on your actual processing pipeline.

  •  Tags:  
  • Related