BharathYes
BharathYes

Reputation: 1037

Leveling select fields

I am fetching a json response of following structure:

{
  "data": {
    "children": [
      {
        "data": {
          "id": "abcdef",
          "preview": {
            "images": [
              {
                "source": {
                  "url": "https://example.com/somefiles_1.jpg"
                }
              }
            ]
          },
          "title": "Boring Title One"
        }
      },
      {
        "data": {
          "id": "ghijkl",
          "preview": {
            "images": [
              {
                "source": {
                  "url": "https://example.com/somefiles_2.jpg"
                }
              }
            ]
          },
          "title": "Boring Title Two"
        }
      },
      {
        "data": {
          "id": "mnopqr",
          "preview": {
            "images": [
              {
                "source": {
                  "url": "https://example.com/somefiles_3.jpg"
                }
              }
            ]
          },
          "title": "Boring Title Three"
        }
      },
      {
        "data": {
          "id": "stuvwx",
          "preview": {
            "images": [
              {
                "source": {
                  "url": "https://example.com/somefiles_4.jpg"
                }
              }
            ]
          },
          "title": "Boring Title Four"
        }
      }
    ]
  }
}

Ideally I would like to have a shortened json like this:

{
    "data": [
        {
            "id": "abcdef",
            "title": "Boring Title One",
            "url": "https://example.com/somefiles_1.jpg"
        },
        {
            "id": "ghijkl",
            "title": "Boring Title Two",
            "url": "https://example.com/somefiles_2.jpg"
        },
        {
            "id": "mnopqr",
            "title": "Boring Title Three",
            "url": "https://example.com/somefiles_3.jpg"
        },
        {
            "id": "stuvwx",
            "title": "Boring Title Four",
            "url": "https://example.com/somefiles_4.jpg"
        }
    ]
}

If this is not possible I can work with joining those three values into a single string and latter split when necessary; like this:

abcdef@Boring Title One@https://example.com/somefiles_1.jpg
ghijkl@Boring Title Two@https://example.com/somefiles_2.jpg
mnopqr@Boring Title Three@https://example.com/somefiles_3.jpg
stuvwx@Boring Title Four@https://example.com/somefiles_4.jpg

This is where I am. I was uring the jq with select() and then pipe the results to to_entries like this:

jq -r '.data.children[] | select(.data.post_type|test("image")?) | .data | to_entries[] | [ .value.title , .value.preview.images[0].source.url ] | join("@")' ~/Documents/json/sample.json
  1. I don't understand what goes after to_entries[]; I have tried multiple variations of .key and .values; Mostly I don't get any result but sometimes I get key pairs I do not intend to select. How to learn the proper syntax for it?
  2. Is creating a flat json out of a nested json like this good or is it better to create the string outputs? I feel the string might be error prone especially with the presence of spaces or special characters.

Upvotes: 0

Views: 72

Answers (2)

oguz ismail
oguz ismail

Reputation: 50795

Apparently what you're looking for is the {field} syntax. You don't need to resort to string outputs.

{ data: [
    .data.children[].data
    | select(has("post_type") and (.post_type | index("image")))
    | {id, title} + (.preview.images[].source | {url})
  # or, if images array always contains one element:
  # | {id, title, url: .preview.images[0].source.url}
  ]
}

Upvotes: 1

peak
peak

Reputation: 116919

A simple solution to the main question is:

{data: [.data.children[]
        | .data
        | {id, title, url: .preview.images[0].source.url} ]}

(The "post_type" seems to have disappeared, but hopefully if it's relevant, you will be able to adapt the above as required. Likewise if .images[1] and beyond are relevant.)

String Output

If you want linear output, you should probably consider CSV or TSV, both of which are supported by jq via @csv and @tsv respectively.

Upvotes: 1

Related Questions