Вопрос или проблема
Как извлечь email
из записи, в которой ключ level
имеет значение 2
из следующего JSON-документа?
Ожидаемый результат:
[email protected]
Любые предложения, пожалуйста?
{
"escalation_policy": {
"on_call": [
{
"level": 2,
"start": "2022-05-25T00:30:00Z",
"end": "2022-05-25T09:30:00Z",
"user": {
"id": "ABOKC",
"name": "Jaavena Dobey",
"email": "[email protected]",
"time_zone": "Tokyo"
}
},
{
"level": 7,
"start": "2022-05-23T01:00:00Z",
"end": "2022-05-30T01:00:00Z",
"user": {
"id": "KLSPSP",
"name": "kosls frank",
"email": "[email protected]",
"time_zone": "Tokyo"
}
},
{
"level": 3,
"start": "2022-05-23T01:00:00Z",
"end": "2022-05-30T01:00:00Z",
"user": {
"id": "SKSPSLSL",
"name": "Smitha Choudhary",
"email": "[email protected]",
"time_zone": "Tokyo"
}
}
]
}
}
Вот так,
- Получите массив объектов.
- Выберите те, у которых уровень равен 2
- Из возвращённого массива выведите email пользователя
Вызов и вывод,
$ jq ".escalation_policy.on_call[] | select( .level == 2) | .user.email" test.json
"[email protected]"
Следующее получает один из email людей на дежурстве, а именно первый с политикой эскалации на уровне вызова, равном 2:
jq -r '.escalation_policy.on_call | map(select(.level == 2)) | first.user.email' file
Вы этого не спрашивали, но следующее даст вам email дежурного, у которого наименьший .level
. Мы делаем это, сортируя массив on_call
и возвращая значение .user.email
из первой отсортированной записи:
jq -r '.escalation_policy.on_call | sort_by(.level) | first.user.email' file
Мы также можем убедиться, что текущее время находится в пределах временных меток .start
и .end
. Мы делаем это, выбирая только релевантные дежурные записи перед их сортировкой, как и прежде:
jq -r '
.escalation_policy.on_call |
map(select( now > (.start|fromdate) and now < (.end|fromdate) )) |
sort_by(.level) | first.user.email' file
Мы можем сделать это, потому что нам повезло иметь даты в формате, который ожидает функция fromdate
в jq
.
Ответ или решение
Для решения поставленной задачи нам необходимо извлечь электронный адрес пользователя из JSON-документа, где значение ключа level
равно 2. Мы будем использовать утилиту jq
, которая позволяет легко манипулировать JSON-данными. Давайте подробно рассмотрим, как этого достичь.
Теоретическая часть
JSON (JavaScript Object Notation) — это текстовый формат обмена данными, широко используемый для передачи структурированных данных через API и в различных веб-приложениях. Когда данные представлены в виде массива объектов, задача может заключаться в фильтрации определённых элементов и извлечении нужной информации, такой как email.
jq
— это мощный инструмент командной строки для обработки JSON. Он позволяет использовать фильтры для выборки, изменения и создания данных, представленных в JSON-формате. Мы используем оператор []
для обращения к массивам, функцию select()
для фильтрации по условиям и конструкцию .
для доступа к вложенным элементам.
Пример
Рассмотрим JSON-документ:
{
"escalation_policy": {
"on_call": [
{
"level": 2,
"user": {
"email": "example@example.com"
}
},
{
"level": 7,
"user": {
"email": "another@example.com"
}
}
]
}
}
Задача: Получить email
пользователя, у которого level
равен 2.
Применение
Чтобы извлечь email, вы можете использовать следующую команду jq
:
jq -r '.escalation_policy.on_call[] | select(.level == 2) | .user.email' file.json
Разбор команды:
.escalation_policy.on_call[]
: получаем массив объектовon_call
.select(.level == 2)
: фильтруем объекты, оставляя только те, гдеlevel
равен 2..user.email
: извлекаемemail
из объектаuser
.
В результате выполнения команды выше будет выведен адрес электронной почты пользователя, удовлетворяющего условиям фильтрации. Такой подход позволяет эффективно извлекать нужную информацию даже из сложных иерархий JSON-данных.
Заключение
Использование jq
для работы с JSON-файлами позволяет значительно упростить процесс выделения нужных данных благодаря мощным средствам фильтрации и обработки. Важно правильно формулировать условия отбора данных и пользоваться возможностями, которые предоставляет инструмент, чтобы решать подобные задачи эффективно и быстро.