jq to output results as JSON
Asked Answered
S

3

13

jq is suppose to

process/filter JSON inputs and producing the filter's results as JSON

However, I found that after the jq process/filter, output result is no longer in JSON format any more.

E.g., https://stedolan.github.io/jq/tutorial/#result5, i.e.,

$ curl -s 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' | jq '.[] | {message: .commit.message, name: .commit.committer.name}'
{
  "message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161",
  "name": "Stephen Dolan"
}
{
  "message": "Reject all overlong UTF8 sequences.",
  "name": "Stephen Dolan"
}
. . . 

Is there any workaround?

UPDATE:

How to wrap the whole return into a json structure of:

{ "Commits": [ {...}, {...}, {...} ] }

I've tried:

jq '.[] | Commits: [{message: .commit.message, name: .commit.committer.name}]'
jq 'Commits: [.[] | {message: .commit.message, name: .commit.committer.name}]'

but neither works.

Sappington answered 17/3, 2018 at 21:32 Comment(1)
This Q/A helped me find a better Github search approach, FYI.Sappington
C
9

Technically speaking, unless otherwise instructed (notably with the -r command-line option), jq produces a stream of JSON entities.

One way to convert an input stream of JSON entities into a JSON array containing them is to use the -s command-line option.

Response to UPDATE

To produce a JSON object of the form:

{ "Commits": [ {...}, {...}, {...} ] }

you could write something like:

jq '{Commits: [.[] | {message: .commit.message, name: .commit.committer.name}]}'

(jq understands the '{Commits: _}' shorthand.)

Codi answered 17/3, 2018 at 22:24 Comment(0)
S
17

Found it, on the same page,

https://stedolan.github.io/jq/tutorial/#result6

If you want to get the output as a single array, you can tell jq to “collect” all of the answers by wrapping the filter in square brackets:

jq '[.[] | {message: .commit.message, name: .commit.committer.name}]'
Sappington answered 17/3, 2018 at 21:46 Comment(1)
Those guy are map, why do I want to have a flux of JSON object?Barbie
C
9

Technically speaking, unless otherwise instructed (notably with the -r command-line option), jq produces a stream of JSON entities.

One way to convert an input stream of JSON entities into a JSON array containing them is to use the -s command-line option.

Response to UPDATE

To produce a JSON object of the form:

{ "Commits": [ {...}, {...}, {...} ] }

you could write something like:

jq '{Commits: [.[] | {message: .commit.message, name: .commit.committer.name}]}'

(jq understands the '{Commits: _}' shorthand.)

Codi answered 17/3, 2018 at 22:24 Comment(0)
V
4

To answer your direct question, if you are doing something like starting with json, then your jq produces a json stream ,

echo '[{"commit": {"message": "hi"}},{"commit": {"message": "okay"}},{"commit": {"message": "bye"}}]' \
    | jq '.[] | {message: .commit.message}'
{
  "message": "hi"
}
{
  "message": "okay"
}
{
  "message": "bye"
}

Then you just --slurp it , like

echo '[{"commit": {"message": "hi"}},{"commit": {"message": "okay"}},{"commit": {"message": "bye"}}]' \
    | jq '.[] | {message: .commit.message}'\
    | jq --slurp
[
  {
    "message": "hi"
  },
  {
    "message": "okay"
  },
  {
    "message": "bye"
  }
]

( NOTE @peak hinted at this , -s is short for --slurp )

Varicocele answered 15/2 at 1:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.