Обработка JSON-данных с использованием jq

LinuxLinuxBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

Добро пожаловать в лабораторию по программированию на Linux с использованием jq! В этой лабораторной работе вы узнаете, как использовать jq — легкий и универсальный командный JSON-процессор. Представьте себе jq как sed, но специально разработанный для работы с JSON-данными. Он позволяет вам легко разделять, фильтровать, отображать и преобразовывать структурированные данные. Эта лабораторная работа построена таким образом, чтобы провести вас от базового до продвинутого использования jq с помощью практических примеров, которые вы можете применить в реальных сценариях, например, при обработке JSON-данных из API или конфигурационных файлов.

Представьте, что вы планируете поездку в Китай и используете туристическое приложение, которое предоставляет информацию о различных достопримечательностях, включая их местоположение, часы работы и отзывы. Бэкенд приложения хранит эти данные в формате JSON. Ваша задача — извлечь определенные части информации, чтобы эффективно спланировать свою поездку. В этой лабораторной работе будет показано, как использовать jq для запроса и манипуляции этими JSON-данными, что позволит вам быстро определить идеальные достопримечательности для посещения.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL linux(("Linux")) -.-> linux/BasicFileOperationsGroup(["Basic File Operations"]) linux(("Linux")) -.-> linux/InputandOutputRedirectionGroup(["Input and Output Redirection"]) linux/BasicFileOperationsGroup -.-> linux/cat("File Concatenating") linux/InputandOutputRedirectionGroup -.-> linux/pipeline("Data Piping") subgraph Lab Skills linux/cat -.-> lab-279945{{"Обработка JSON-данных с использованием jq"}} linux/pipeline -.-> lab-279945{{"Обработка JSON-данных с использованием jq"}} end

Базовый запрос к JSON

Начнем с изучения того, как извлекать простые данные из JSON-объекта.

Теперь у вас должен быть файл data.txt в директории /home/labex/project/. Он содержит JSON-данные, представляющие список достопримечательностей. Содержимое файла выглядит следующим образом:

[
  {
    "name": "The Great Wall of China",
    "location": "Shanxi Province",
    "opening_hours": "24 hours"
  },
  {
    "name": "Terracotta Warriors",
    "location": "XiAn",
    "opening_hours": "9:00 AM -  5:00 PM"
  }
]

Наша цель здесь — извлечь имена всех достопримечательностей, перечисленных в этих JSON-данных.

Для этого используйте следующую команду:

cat ~/project/data.txt | jq '.[] |.name'

Эта команда выдаст следующий результат:

"The Great Wall of China"
"Terracotta Warriors"

Разберем, что происходит в этой команде. cat ~/project/data.txt просто считывает содержимое файла data.txt. Символ |, известный как "pipe" (канал), берет вывод команды cat и передает его в качестве входных данных команде jq. Ядро логики извлечения находится в jq '.[] |.name'. Вот как jq обрабатывает это:

  • .[] сообщает jq обойти каждый элемент (в данном случае, каждый объект достопримечательности) в JSON-массиве.
  • | снова передает результат итерации в следующую операцию, в данном случае .name.
  • .name извлекает значение, связанное с ключом "name" из каждого объекта достопримечательности.

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

Фильтрация JSON-данных

Перейдем к фильтрации JSON-данных на основе определенных критериев.

Наша цель — найти только те достопримечательности, которые работают круглосуточно.

Для этого используйте следующую команду:

cat ~/project/data.txt | jq '.[] | select(.opening_hours == "24 hours") |.name'

При выполнении этой команды будет выведено:

"The Great Wall of China"

Вот как работает фильтрация: Команда начинается с cat ~/project/data.txt | jq '.[]', которая, как и раньше, считывает файл и проходит по каждой достопримечательности. Ключевой частью является добавление select(.opening_hours == "24 hours"):

  • select() — это функция jq, которая позволяет фильтровать элементы JSON на основе условия, которое вы задаете.
  • Условие .opening_hours == "24 hours" проверяет, равно ли значение поля opening_hours именно строке "24 hours". Только те достопримечательности, которые соответствуют этому условию, будут переданы на следующую стадию.
  • Последняя часть, |.name, просто извлекает имя каждой достопримечательности, которая прошла фильтр.

В данном случае только "The Great Wall of China" соответствует условию, поэтому это единственное имя, которое извлекается и отображается.

Преобразование JSON-данных

Теперь давайте узнаем, как преобразовать JSON-данные в другой, более полезный формат.

Наша цель здесь — сделать часы работы более читаемыми. В частности, если достопримечательность работает круглосуточно, мы хотим отобразить "Open 24 hours"; в противном случае мы добавим префикс "Open " к существующему тексту о часах работы.

Для этого используйте следующую команду:

cat ~/project/data.txt | jq '.[] | {name:.name, location:.location, opening_hours: (.opening_hours | if. == "24 hours" then "Open 24 hours" else "Open \(.)" end)}'

Эта команда выдаст следующий результат:

{
  "name": "The Great Wall of China",
  "location": "Shanxi Province",
  "opening_hours": "Open 24 hours"
}
{
  "name": "Terracotta Warriors",
  "location": "XiAn",
  "opening_hours": "Open 9:00 AM -  5:00 PM"
}

Понять преобразование: Как и раньше, cat ~/project/data.txt | jq '.[]' запускает процесс, считывая файл и проходя по каждой достопримечательности в массиве. Ядро этого преобразования заключается в построении объекта и операторе if-else:

  • {name:.name, location:.location, opening_hours:...} создает новый JSON-объект, извлекая данные из исходного объекта. Он включает name и location из исходного объекта напрямую. Однако значение поля opening_hours более сложно.
  • (.opening_hours | if. == "24 hours" then "Open 24 hours" else "Open \(.)" end) берет значение исходного opening_hours и обрабатывает его:
    • .opening_hours выбирает исходное значение часов работы.
    • Оператор if. == "24 hours" then "Open 24 hours" else "Open \(.)" end проверяет, равно ли исходное opening_hours именно "24 hours". Если это так, значение заменяется на "Open 24 hours". Если нет, к существующему opening_hours добавляется префикс "Open ". Обратите внимание на использование \(.), которое позволяет вставить значение в строку.

По сути, эта команда преобразует данные, создавая новый объект для каждой достопримечательности и корректируя значение opening_hours, чтобы оно было более читаемым для пользователя.

Заключение

Поздравляем! Вы успешно завершили лабораторную работу по программированию на Linux с использованием jq. Вы научились запрашивать, фильтровать и преобразовывать JSON-данные с помощью jq — мощного инструмента для работы со структурированными данными прямо из командной строки. Независимо от того, обрабатываете ли вы данные из API, конфигурационных файлов или любого другого JSON-источника, jq позволяет вам эффективно и четко извлекать, фильтровать и манипулировать необходимыми данными.

Помните, что регулярная практика является важной частью освоения jq и других инструментов командной строки. Не стесняйтесь экспериментировать с собственными JSON-данными, пробуя различные запросы и преобразования. Успешного программирования!