Выравнивание полей выбора

Я получаю ответ json следующей структуры:

{
  "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"
        }
      }
    ]
  }
}

В идеале я хотел бы иметь укороченный json следующим образом:

{
    "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"
        }
    ]
}

Если это невозможно, я могу работать с объединением этих трех значений в одну строку, а затем при необходимости разделить ее; так:

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

Вот где я. Я выполнял jq с select(), а затем передал результаты to_entries следующим образом:

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. Я не понимаю, что идет после to_entries[]; Я пробовал несколько вариантов .key и .values; В основном я не получаю никакого результата, но иногда я получаю пары ключей, которые я не собираюсь выбирать. Как выучить правильный синтаксис для этого?
  2. Хорошо ли создавать плоский json из вложенного json или лучше создавать строковые выходные данные? Я чувствую, что строка может быть подвержена ошибкам, особенно при наличии пробелов или специальных символов.

В вашем образце нет поля post_type.

oguz ismail 24.12.2020 08:48
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
0
1
68
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Очевидно, вы ищете синтаксис {field}. Вам не нужно прибегать к строковым выводам.

{ 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}
  ]
}

это работает, включая фильтрацию по типу post_type. Я ожидал, что создание нового json будет сложным, поэтому искал строку.

BharathYes 24.12.2020 10:34

не уверен, должен ли я задать это как новый вопрос или нет .... может ли select(has(key)) использоваться для добавления значения, если ключ существует, а если нет, добавить значение из другой пары? Например, если video_url существует, добавьте его в ключ url, иначе добавьте значение image_url в ключ url? Я понимаю, что это далеко от вопроса и приведенного выше примера.

BharathYes 24.12.2020 10:42

@Bahrath да, я думаю, вам следует задать это как отдельный вопрос.

oguz ismail 24.12.2020 10:45

Простое решение главного вопроса:

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

(«Похоже, что «post_type» исчез, но, надеюсь, если это актуально, вы сможете адаптировать вышеприведенное по мере необходимости. Аналогично, если .images[1] и другие актуальны.)

Строковый вывод

Если вам нужен линейный вывод, вам, вероятно, следует рассмотреть CSV или TSV, оба из которых поддерживаются jq через @csv и @tsv соответственно.

часть URL интересна. Это помогло бы мне добавить больше пар "ключ-значение", вложенных в разные места. это с ответом Огуза работает так, как я хотел.

BharathYes 24.12.2020 10:37

Другие вопросы по теме