Неожиданно сильный PowerShell (из цикла «Открытия никсоида»)

Summary - Задача: извлечь данные из JSON, но установка привычного инструмента jq невозможна из-за строгих ИБ-ограничений в рабочей среде. - Решение найдено в встроенном PowerShell, который умеет парсить JSON без дополнительного ПО. - Несмотря на отличие от jq, PowerShell эффективно справляется с задачей и подходит для ограниченных Windows-сред.

Детали:

Недавно понадобилось мне обработать небольшой JSON-файлик, строк на 50 - вытащить из него значения одного из полей. В принципе, руками я бы справился с этой задачей минут за 10. Но, пара нюансов, а именно - стремление все автоматизировать и предположение, что этот файлик далеко не последний - подтолкнули меня к поиску инструмента, способного мою задачу выполнить с меньшими усилиями.

В обычной ситуации все решается при помощи какого-нибудь jq. Но это в обычной. А здесь - ВРМ заказчика, на котором установлено ограниченное количество “проверенного” софта и чтобы установить что-то еще, нужно пройти несколько кругов ада (включая ИБ).

В итоге, имеем винду с фиксированным набором ПО и без намека на jq или что-то на него похожее. Пошел за подсказкой к своим коллегам - может есть какой-то выход? А сам приготовился уже копи-пастом нужную мне информацию вытаскивать.

Спасение пришло, как говорится, откуда не ждали. А именно, из штатного виндового PowerShell. Да-да. Я был немало удивлен, когда узнал, что он из коробки умеет парсить JSON. Синтаксис там, конечно, совершенно отличается от jq. Что, впрочем, не мешает powershell справляться с нужной мне задачей.

Ну вот, возьмем, к примеру, такой кусочек данных из файла user.json: json { “user”: { “id”: 12345, “name”: “Алексей Петров”, “email”: “alexey.petrov@example.com”, “active”: true, “roles”: [“user”, “admin”], “profile”: { “department”: “IT”, “location”: “Москва” } } }

И нужно нам вытащить значения поля “email”. Но не просто так, а только оттуда, где “department” = “IT”.

В jq бы это выглядело так:

jq -r ‘if .user.profile.department == “IT” then .user.email else empty end’ user.json

или так:

jq -r ‘select(.user.profile.department == “IT”) | .user.email’ user.json

В PowerShell же, в лучших традициях Windows-style, все выглядит оригинальнее (как минимум потому, что здесь объектный подход) - сначала нужно получить содержимое файла методом Get-Content, затем скормить его методу ConvertFrom-Json. Но в итоге, все тот же if: powershell $data = Get-Content -Path .user.json | ConvertFrom-Json if ($data.user.profile.department -eq “IT”) { $data.user.email }

Еще интереснее, если данные в нашем JSON упакованы в массив - тут уже и where (почти как в SQL) и for each: powershell (Get-Content .users.json | ConvertFrom-Json).users | Where-Object { $.profile.department -eq “IT” } | ForEach-Object { $.email }

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

Пользуйтесь.

Неожиданно сильный PowerShell (из цикла «Открытия никсоида»)
Summary
- Задача: извлечь данные из JSON, но установка привычного инструмента jq невозможна из-за строгих ИБ-ограничений в рабочей среде | Сетка — социальная сеть от hh.ru