Фильтровать ключи на различных уровнях из большого сложного вложенного json

#json #jq

#json #jq

Вопрос:

Проблема

У меня есть список видеороликов YouTube, и я хочу получить их id name и изображение предварительного просмотра. Я использую youtube-dl для получения вывода json, который я анализирую для ключей id title и вложенного массива thumbnails .

Ввод

В качестве тематического примера видео давайте рассмотрим посадку perseverance:

 youtube-dl -j "https://www.youtube.com/watch?v=4czjS9h4Fpg" | jq -r '[.id, .title, .thumbnails]'
 

Это возвращает следующий json:

 [
  "4czjS9h4Fpg",
  "Perseverance Rover’s Descent and Touchdown on Mars (Official NASA Video)",
  [
    {
      "height": 94,
      "url": "https://i.ytimg.com/vi/4czjS9h4Fpg/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEGamp;rs=AOn4CLBeXaobqWQ3MHAvEzLHQtitoAKKow",
      "width": 168,
      "resolution": "168x94",
      "id": "0"
    },
    {
      "height": 110,
      "url": "https://i.ytimg.com/vi/4czjS9h4Fpg/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEGamp;rs=AOn4CLB2j8DNX2ZOyXHUS2MwRz4gG8admQ",
      "width": 196,
      "resolution": "196x110",
      "id": "1"
    },
    {
      "height": 138,
      "url": "https://i.ytimg.com/vi/4czjS9h4Fpg/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==amp;rs=AOn4CLDUIrTqT-g6F5z62q_Jq2RXy3AydQ",
      "width": 246,
      "resolution": "246x138",
      "id": "2"
    },
    {
      "height": 188,
      "url": "https://i.ytimg.com/vi/4czjS9h4Fpg/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==amp;rs=AOn4CLDtiAfOuC4lgjiMxXeJ3qIh7uV6Zg",
      "width": 336,
      "resolution": "336x188",
      "id": "3"
    },
    {
      "height": 1080,
      "url": "https://i.ytimg.com/vi/4czjS9h4Fpg/maxresdefault.jpg",
      "width": 1920,
      "resolution": "1920x1080",
      "id": "4"
    }
  ]
]
 

На данный момент я не особенно забочусь о выборе какого-либо конкретного изображения заголовка видео и с радостью возьму все. Я хотел бы обработать их дальше как CSV и знать, что после выбора соответствующего ключа / значений я могу передать его | @csv , но это выбор, который я немного потерял.

Ожидаемый результат

В идеале вывод должен выглядеть следующим образом:

 "4czjS9h4Fpg","Perseverance Rover’s Descent and Touchdown on Mars (Official NASA Video)","168x94","https://i.ytimg.com/vi/4czjS9h4Fpg/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEGamp;rs=AOn4CLBeXaobqWQ3MHAvEzLHQtitoAKKow","196x110","https://i.ytimg.com/vi/4czjS9h4Fpg/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEGamp;rs=AOn4CLB2j8DNX2ZOyXHUS2MwRz4gG8admQ","246x138","https://i.ytimg.com/vi/4czjS9h4Fpg/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==amp;rs=AOn4CLDUIrTqT-g6F5z62q_Jq2RXy3AydQ","336x188","https://i.ytimg.com/vi/4czjS9h4Fpg/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==amp;rs=AOn4CLDtiAfOuC4lgjiMxXeJ3qIh7uV6Zg","1920x1080","https://i.ytimg.com/vi/4czjS9h4Fpg/maxresdefault.jpg",
 

Псевдокод / Python?

В более питоническом смысле это то, что я ищу в выходных данных. Я предполагаю, что я мог бы передать json на python или около того, но я думаю, что это тоже должно быть просто сделать jq , нет?

 $id,$title,($thumbnails.resolution,$thumbnails.url for item in thumbnails)
 

Ответ №1:

Вы можете использовать map для расширения каждого объекта в третьем элементе до resolution и url .

 .[:2]   (.[2] | map(.resolution, .url)) | @csv
 

Онлайн-демонстрация

В качестве альтернативы, подход, основанный на исключениях, подобный приведенному ниже, также даст тот же результат, учитывая ваш пример ввода.

 map((.[] | .resolution, .url)? // .) | @csv
 

Онлайн-демонстрация

Комментарии:

1. Идеально, работает именно так, как рекламируется, и именно то, что я искал, спасибо 🙂