Parsing JSON record-per-line with jq?

Roger Lipscombe picture Roger Lipscombe · Aug 16, 2017 · Viewed 11k times · Source

I've got a tool that outputs a JSON record on each line, and I'd like to process it with jq.

The output looks something like this:

{"ts":"2017-08-15T21:20:47.029Z","id":"123","elapsed_ms":10}
{"ts":"2017-08-15T21:20:47.044Z","id":"456","elapsed_ms":13}

When I pass this to jq as follows:

./tool | jq 'group_by(.id)'

...it outputs an error:

jq: error (at <stdin>:1): Cannot index string with string "id"

How do I get jq to handle JSON-record-per-line data?

Answer

Roger Lipscombe picture Roger Lipscombe · Aug 16, 2017

Use the --slurp (or -s) switch:

./tool | jq --slurp 'group_by(.id)'

It outputs the following:

[
  [
    {
      "ts": "2017-08-15T21:20:47.029Z",
      "id": "123",
      "elapsed_ms": 10
    }
  ],
  [
    {
      "ts": "2017-08-15T21:20:47.044Z",
      "id": "456",
      "elapsed_ms": 13
    }
  ]
]

...which you can then process further. For example:

./tool | jq -s 'group_by(.id) | map({id: .[0].id, count: length})'