Инструкции по получению Crystal можно найти в
Все примеры кода, использованные в этой главе, можно найти в папке Chapter 4 на GitHub: https://github.com/PacktPublishing/Crystal-Programming/ tree/main/Chapter04.
Введение в проект
Прежде чем мы перейдем к нашему CLI-приложению, было бы полезно немного понять, как работает jq, поскольку он является основной частью желаемой функциональности нашего приложения. Как упоминалось ранее, jq позволяет создавать фильтры, которые используются для описания того, как следует преобразовать входные данные JSON.
Фильтр состоит из строки различных символов и символов, некоторые из которых имеют особое значение. Самый простой фильтр — .
, также известный как
jq включает в себя различные другие фильтры, целью которых является доступ к определенным частям входных данных или управление выполнением фильтра. Наиболее распространенными из них являются следующие:
• Индекс идентификатора объекта
• Индекс массива
• Запятая
• Pipe
Фильтр индекса идентификатора объекта позволяет получить доступ к значению по определенному ключу, предполагая, что входные данные являются объектом, и выдает ошибку, если это не так. Этот фильтр вернет значение null
, если нужный ключ отсутствует в объекте. Например, использование фильтра .name
для входных данных {"id":1,"name":"George"}
приведет к получению выходного значения "George"
. Фильтр индекса массива работает во многом аналогично фильтру индекса идентификатора объекта, но для входных данных массива. Учитывая входные данные [1, 2, 3]
, использование фильтра .[1]
даст выход 2
.
Хотя первые два примера посвящены доступу к данным, фильтры «Запятая» и «Канал» предназначены для управления потоком данных через фильтр. Если несколько фильтров разделены запятой, входные данные передаются каждому фильтру независимо. Например, используя ранее полученный входной объект, фильтр .id
, .name
выдает выходные данные 1
и "George"
, каждое в отдельной строке. С другой стороны, канал передает выходные данные фильтра слева в качестве входных данных для фильтра справа. Опять же, используя тот же ввод, что и раньше, фильтр .id | . + 1
выдаст результат 2
. Обратите внимание, что в этом примере мы используем идентификационный фильтр для ссылки на выходное значение предыдущего фильтра, которое в этом примере было равно 1
, которое изначально пришло из входного объекта.
Доступ к определенным значениям из входных данных — это только половина дела, когда дело доходит до преобразования данных. jq предоставляет способ создания новых объектов/массивов с использованием синтаксиса JSON. Используя проверенный входной объект, который мы использовали, фильтр {"new_id":(.id+2)}
создает новый объект, который выглядит как {"new_id":3}
. Аналогично, массив можно создать с помощью синтаксиса []
и [(.id), (.id*2), (.id)]
создает массив [1, 2, 1]
. В обоих последних примерах мы используем круглые скобки, чтобы контролировать порядок операций оценки фильтра.
Давайте объединим все эти функции в более сложный пример, учитывая следующие входные данные:
[
{
"id": 1,
"author": {
"name": "Jim"
}
},
{
"id": 2,
"author": {
"name": "Bob"
}
}
]
Мы можем использовать фильтр [.[] | {"id": (.id + 1), "name": .author.name}]
для получения следующего вывода, полная команда — jq '[.[] | {"id": (.id + 1), "name": .author.name}]' input.json
:
[
{
"id": 2,
"name": "Jim"
},
{
"id": 3,
"name": "Bob"
}
]
Если вы хотите узнать больше о возможностях jq, ознакомьтесь с его документацией по адресу https://stedolan.github.io/jq/manual, поскольку существует множество вариантов, методов и функций, выходящих за рамки этой книги.
Теперь, когда вы познакомились с синтаксисом jq, давайте перейдем к его применению для нашего собственного приложения, начиная с его терминологической структуры.
Строительные леса проекта