Программа jq-это «фильтр»:она принимает входные данные и выдает выходные.Существует множество встроенных фильтров для извлечения определенного поля объекта,преобразования числа в строку и других стандартных задач.
Фильтры можно комбинировать различными способами-вы можете направить вывод одного фильтра в другой фильтр или собрать вывод фильтра в массив.
Некоторые фильтры дают несколько результатов,например,есть фильтр,который выдает все элементы входного массива.Передача этого фильтра во второй запускает второй фильтр для каждого элемента массива.В целом,то,что в других языках делается с помощью циклов и итераций,в jq делается путем склеивания фильтров.
Важно помнить, что у каждого фильтра есть вход и выход. Даже такие литералы, как «hello» или 42, являются фильтрами — они принимают входные данные, но всегда производят тот же литерал, что и выходные. Операции, объединяющие два фильтра, например сложение, обычно передают один и тот же ввод в оба и объединяют результаты. Таким образом, вы можете реализовать фильтр усреднения как add / length
— подавая входной массив как в фильтр add
и в фильтр length
а затем выполняя деление.
Но это уже забегание вперед :).Давайте начнем с чего-то более простого:
Invoking jq
Фильтры jq работают с потоком данных JSON.Входные данные для jq разбираются как последовательность разделенных пробелами значений JSON,которые пропускаются через предоставленный фильтр по одному за раз.Вывод(ы)фильтра записывается в стандартный выход,опять же как последовательность JSON-данных,разделенных пробелами.
Примечание: важно помнить о правилах цитирования оболочки. Как правило, лучше всегда заключать jq-программу в кавычки (с одинарными кавычками), так как слишком много символов со специальным значением для jq также являются метасимволами оболочки. Например, jq "foo"
завершится ошибкой в большинстве оболочек Unix, потому что это будет то же самое, что и jq foo
, что обычно не работает, потому что foo is not defined
. При использовании командной оболочки Windows (cmd.exe) лучше всего использовать двойные кавычки вокруг вашей программы jq, когда она указана в командной строке (вместо параметра -f program-file
), но тогда нужны двойные кавычки в программе jq. экранирование обратной косой черты.
Вы можете повлиять на то,как jq читает и записывает свои входные и выходные данные,используя некоторые параметры командной строки:
--version
:
Вывести версию jq и выйти с нулем.
--seq
:
Используйте схему типа MIME application/json-seq
для разделения текстов JSON на входе и выходе jq. Это означает, что символ ASCII RS (разделитель записей) печатается перед каждым значением на выходе, а ASCII LF (перевод строки) печатается после каждого вывода. Входные тексты JSON, которые не удается проанализировать, игнорируются (но предупреждаются), отбрасывая все последующие входные данные до следующего RS. Этот режим также анализирует вывод jq без опции --seq
.
--stream
:
Анализируйте ввод в потоковом режиме, выводя массивы значений путей и листьев (скаляры и пустые массивы или пустые объекты). Например, "a"
становится [[],"a"]
, а [[],"a",["b"]]
становится [[0],[]]
, [[1],"a"]
, и [[1,0],"b"]
.
Это полезно для обработки очень больших входных данных. Используйте это в сочетании с фильтрацией и синтаксисом reduce
и foreach
для постепенного уменьшения больших входных данных.
--slurp
/-s
:
Вместо того чтобы запускать фильтр для каждого объекта JSON на входе,считайте весь входной поток в большой массив и запустите фильтр только один раз.
--raw-input
/-R
:
Не анализируйте ввод как JSON. Вместо этого каждая строка текста передается фильтру в виде строки. В сочетании с --slurp
весь ввод передается фильтру как одна длинная строка.
--null-input
/-n
:
Вообще не читайте никаких вводных! Вместо этого фильтр запускается один раз с использованием null
в качестве входных данных. Это полезно при использовании jq в качестве простого калькулятора или для создания данных JSON с нуля.
--compact-output
/-c
:
По умолчанию jq распечатывает JSON-файлы.Использование этой опции приведет к более компактному выводу,поскольку каждый объект JSON будет размещен в одной строке.
--tab
:
Используйте табуляцию для каждого уровня отступа вместо двух пробелов.
--indent n
:
Используйте заданное количество пробелов (не более 7)для отступа.
--color-output
/-C
и--monochrome-output
/-M
:
По умолчанию jq выводит цветной JSON при записи в терминал. Вы можете заставить его выдавать цвет даже при записи в канал или файл с помощью -C
и отключить цвет с помощью -M
.
Цвета можно настроить с помощью переменной среды JQ_COLORS
(см. Ниже).
--ascii-output
/-a
:
jq обычно выводит кодовые точки Юникода,не являющиеся символами ASCII,в формате UTF-8,даже если в исходном тексте они указаны как управляющие последовательности (например,»u03bc»).Используя эту опцию,вы можете заставить jq выдавать чистый ASCII вывод с заменой каждого не-ASCII символа на эквивалентную управляющую последовательность.
--unbuffered
Промывайте вывод после печати каждого объекта JSON (полезно,если вы передаете медленный источник данных в jq и передаете вывод jq в другое место).
--sort-keys
/-S
:
Выведите поля каждого объекта с ключами в отсортированном порядке.
--raw-output
/-r
:
При использовании этой опции,если результат фильтра является строкой,то он будет записан непосредственно в стандартный вывод,а не отформатирован как строка JSON с кавычками.Это может быть полезно для того,чтобы заставить фильтры jq общаться с системами,не основанными на JSON.
--join-output
/-j
:
Подобно -r
, но jq не будет печатать новую строку после каждого вывода.
-f filename
/--from-file filename
:
Чтение фильтра из файла,а не из командной строки,подобно опции awk -f.Вы также можете использовать ‘#’,чтобы сделать комментарии.
-Ldirectory
/-L directory
:
Добавьте directory
к списку поиска модулей. Если используется эта опция, то встроенный список поиска не используется. См. Раздел о модулях ниже.
-e
/--exit-status
:
Устанавливает статус выхода jq равным 0, если последние выходные значения не были ни false
ни null
, 1, если последнее выходное значение было false
или null
, или 4, если действительный результат никогда не был получен. Обычно jq завершается с 2, если возникла проблема использования или системная ошибка, 3, если была ошибка компиляции программы jq, или 0, если программа jq была запущена.
Другой способ установить статус выхода — halt_error
встроенную функцию halt_error .
--arg name value
:
Эта опция передает значение программе jq как предопределенную переменную. Если вы запустите jq с --arg foo bar
, тогда $foo
будет доступен в программе и имеет значение "bar"
. Обратите внимание, что value
будет рассматриваться как строка, поэтому --arg foo 123
привяжет $foo
к "123"
.
Именованные аргументы также доступны программе jq как $ARGS.named
. named .
--argjson name JSON-text
:
Этот параметр передает значение в кодировке JSON в программу jq как предопределенную переменную. Если вы запустите jq с --argjson foo 123
, тогда $foo
будет доступен в программе и имеет значение 123
.
--slurpfile variable-name filename
:
Эта опция считывает все тексты JSON в названном файле и привязывает массив проанализированных значений JSON к данной глобальной переменной. Если вы запускаете jq с --slurpfile foo bar
, тогда $foo
доступен в программе и имеет массив, элементы которого соответствуют текстам в файле с именем bar
.
--rawfile variable-name filename
:
Эта опция считывает названный файл и привязывает его содержимое к данной глобальной переменной. Если вы запускаете jq с --rawfile foo bar
, тогда $foo
доступен в программе и имеет строку, содержимое которой соответствует тексам в файле с именем bar
.
--argfile variable-name filename
:
Не использовать. --slurpfile
этого используйте —slurpfile .
(Этот параметр похож на --slurpfile
, но когда файл содержит только один текст, он используется, иначе используется массив текстов, как в --slurpfile
.)
--args
:
Остальные аргументы являются позиционными строковыми аргументами. Они доступны программе jq как $ARGS.positional[]
.
--jsonargs
:
Остальные аргументы являются позиционными текстовыми аргументами JSON. Они доступны программе jq как $ARGS.positional[]
.
--run-tests [filename]
:
Запускает тесты в указанном файле или стандартном вводе.Эта опция должна быть последней и не учитывает все предыдущие опции.Входные данные состоят из строк комментариев,пустых строк и строк программы,за которыми следует одна строка ввода,столько строк вывода,сколько ожидается (по одной на вывод),и завершающая пустая строка.Тесты на неудачу компиляции начинаются со строки,содержащей только «%%FAIL»,затем строку,содержащую программу для компиляции,затем строку,содержащую сообщение об ошибке для сравнения с фактическим.
Будьте предупреждены,что этот параметр может изменяться в обратную сторону несовместимо.
Basic filters
Identity: .
Самый простой фильтр — это .
. Это фильтр, который принимает входные данные и производит их без изменений на выходе. То есть это оператор идентичности.
Поскольку jq по умолчанию красиво печатает весь вывод, эта тривиальная программа может быть полезным способом форматирования вывода JSON, скажем, из curl
.
Важным моментом в фильтре идентичности является то,что он гарантирует сохранение буквального десятичного представления значений.Это особенно важно при работе с числами,которые не могут быть без потерь преобразованы в представление двойной точности IEEE754.
jq не усекает литеральные числа до двойки,если нет необходимости выполнять арифметические операции с числом.Сравнения выполняются над неусеченным большим десятичным представлением числа.
jq также попытается сохранить исходную десятичную точность предоставленного литерала числа.Примеры смотрите ниже.
Examples
jq ‘.’ | |
Input | «Hello, world!» |
Output | «Hello, world!» |
jq ‘.| tojson’ | |
Input | 12345678909876543212345 |
Output | «12345678909876543212345» |
jq ‘map([.,.==1])| tojson’ | |
Input | [1, 1.000, 1.0, 100e-2] |
Output | «[[1,true],[1.000,true],[1.0,true],[1.00,true]]» |
jq ‘. как $ большой | [$ большой, $ большой + 1] | карта (.> 10000000000000000000000000000000) ‘ | |
Input | 10000000000000000000000000000001 |
Output | [true, false] |
Индекс идентификатора объекта: .foo
, .foo.bar
Самый простой полезный фильтр — это .foo
. Когда в качестве входных данных используется объект JSON (он же словарь или хеш), он выдает значение по ключу «foo» или null, если его нет.
Фильтр вида .foo.bar
эквивалентен .foo|.bar
.
Этот синтаксис работает только для простых,похожих на идентификаторы ключей,то есть ключей,состоящих из буквенно-цифровых символов и подчеркивания,и не начинающихся с цифры.
Если ключ содержит специальные символы или начинается с цифры, вам необходимо заключить его в двойные кавычки, например:. ."foo$"
или иначе .["foo$"]
.
Например .["foo::bar"]
и .["foo.bar"]
работают, а .foo::bar
— нет, а .foo.bar
означает .["foo"].["bar"]
.
Examples
jq ‘.foo’ | |
Input | {«foo»: 42, «bar»: «менее интересные данные»} |
Output | 42 |
jq ‘.foo’ | |
Input | {«notfoo»: правда, «alsonotfoo»: ложь} |
Output | null |
jq ‘.[«foo»]’ | |
Input | {«foo»: 42} |
Output | 42 |
Необязательный индекс идентификатора объекта: .foo?
То же, что и .foo
, но не выводит даже ошибку, когда .
не является массивом или объектом.
Examples
jq ‘.foo?’ | |
Input | {«foo»: 42, «bar»: «менее интересные данные»} |
Output | 42 |
jq ‘.foo?’ | |
Input | {«notfoo»: правда, «alsonotfoo»: ложь} |
Output | null |
jq ‘.[«foo»]?’ | |
Input | {«foo»: 42} |
Output | 42 |
jq ‘[.foo?]’ | |
Input | [1,2] |
Output | [] |
Общий индекс объекта:. .[<string>]
Вы также можете искать поля объекта, используя синтаксис типа .["foo"]
(.foo выше является сокращенной версией этого, но только для строк, подобных идентификатору).
Индекс массива:. .[2]
Когда значение индекса является целым числом,. .[<value>]
может индексировать массивы. Массивы начинаются с нуля, поэтому .[2]
возвращает третий элемент.
Допускаются отрицательные индексы,при этом -1 обозначает последний элемент,-2-предпоследний элемент и так далее.
Examples
jq ‘.[0]’ | |
Input | [{«name»:»JSON», «good»:true}, {«name»:»XML», «good»:false}] |
Output | {«name»:»JSON», «good»:true} |
jq ‘.[2]’ | |
Input | [{«name»:»JSON», «good»:true}, {«name»:»XML», «good»:false}] |
Output | null |
jq ‘.[-2]’ | |
Input | [1,2,3] |
Output | 2 |
Массив / фрагмент строки:. .[10:15]
.[10:15]
синтаксис может быть использован для возврата подмассива массива или подстрок строки. Массив, возвращаемый функцией .[10:15]
, будет иметь длину 5 и содержать элементы от индекса 10 (включительно) до индекса 15 (исключая). Любой индекс может быть отрицательным (в этом случае он считается в обратном направлении от конца массива) или опущен (в этом случае он относится к началу или концу массива).
Examples
jq ‘.[2:4]’ | |
Input | [«a»,»b»,»c»,»d»,»e»] |
Output | [«c», «d»] |
jq ‘.[2:4]’ | |
Input | «abcdefghi» |
Output | «cd» |
jq ‘.[:3]’ | |
Input | [«a»,»b»,»c»,»d»,»e»] |
Output | [«а», «б», «в»] |
jq ‘.[-2:]’ | |
Input | [«a»,»b»,»c»,»d»,»e»] |
Output | [«d», «e»] |
Итератор значений массива / объекта:. .[]
Если вы используете синтаксис .[index]
, но полностью опустите индекс, он вернет все элементы массива. Запуск .[]
С входом [1,2,3]
даст числа как три отдельных результата, а не как единый массив.
Вы также можете использовать эту функцию для объекта,и она вернет все значения объекта.
Examples
jq ‘.[]’ | |
Input | [{«name»:»JSON», «good»:true}, {«name»:»XML», «good»:false}] |
Output | {«name»:»JSON», «good»:true} |
{«name»:»XML», «good»:false} |
jq ‘.[]’ | |
Input | [] |
Output | none |
jq ‘.[]’ | |
Input | {«a»: 1, «b»: 1} |
Output | 1 |
1 |
.[]?
Подобно .[]
, Но если. не является массивом или объектом.
Comma: ,
Если два фильтра разделены запятой, то один и тот же ввод будет подаваться в оба, и потоки выходных значений двух фильтров будут объединены по порядку: сначала все выходные данные, созданные левым выражением, а затем все выходы. производится по праву. Например, фильтр .foo, .bar
создает как поля «foo», так и поля «bar» как отдельные выходные данные.
Examples
jq ‘.foo,.bar’ | |
Input | {«foo»: 42, «bar»: «что-то еще», «baz»: правда} |
Output | 42 |
«something else» |
jq ‘.user,.projects[]’ | |
Input | {«пользователь»: «стедолан», «проекты»: [«jq», «wikiflow»]} |
Output | «stedolan» |
«jq» | |
«wikiflow» |
jq ‘.[4,2]’ | |
Input | [«a»,»b»,»c»,»d»,»e»] |
Output | «e» |
«c» |
Pipe: |
Оператор | объединяет два фильтра,подавая выход(ы)фильтра слева на вход фильтра справа.Это практически то же самое,что и pipe в Unix shell,если вы привыкли к нему.
Если один слева дает несколько результатов, один справа будет запускаться для каждого из этих результатов. Итак, выражение .[] | .foo
извлекает поле «foo» каждого элемента входного массива.
Обратите внимание, что .a.b.c
— это то же самое, что .a .a | .b | .c
.
Обратите внимание тоже на это .
— это входное значение на конкретном этапе «конвейера», а именно: где .
появляется выражение. Таким образом .a | . | .b
— это то же самое, что .a.b
, как .
в середине относится к произведенному значению .a
.
Example
jq ‘.[]| .name’ | |
Input | [{«name»:»JSON», «good»:true}, {«name»:»XML», «good»:false}] |
Output | «JSON» |
«XML» |
Parenthesis
Круглые скобки работают как оператор группировки,как и в любом обычном языке программирования.
Example
jq ‘(.+2)*5’ | |
Input | 1 |
Output | 15 |
Типы и значения
jq поддерживает тот же набор типов данных,что и JSON-числа,строки,булевы,массивы,объекты (которые,говоря языком JSON,представляют собой хэши с ключами,состоящими только из строк)и «null».
Логические значения, null, строки и числа записываются так же, как в javascript. Как и все остальное в jq, эти простые значения принимают входные данные и производят выходные данные — 42
— допустимое выражение jq, которое принимает входные данные, игнорирует их и вместо этого возвращает 42.
Числа в jq внутренне представлены их аппроксимацией двойной точности IEEE754.Любая арифметическая операция с числами,будь то литералы или результаты предыдущих фильтров,дает результат с плавающей точкой двойной точности.
Однако при разборе литерала jq сохраняет исходную строку литерала.Если к этому значению не применяется мутация,то оно будет выведено в исходном виде,даже если преобразование в double приведет к потере.
Конструкция массива: []
Как и в JSON, []
используется для создания массивов, как в [1,2,3]
. Элементами массивов может быть любое выражение jq, включая конвейер. Все результаты, полученные всеми выражениями, собираются в один большой массив. Вы можете использовать его для создания массива из известного количества значений (как в [.foo, .bar, .baz]
) или для «сбора» всех результатов фильтра в массив (как в [.items[].name]
)
Как только вы разберетесь с оператором «,», вы сможете взглянуть на синтаксис массива jq в другом свете: выражение [1,2,3]
не использует встроенный синтаксис для массивов, разделенных запятыми, а вместо этого применяет []
(сбор результатов) в выражение 1,2,3 (которое дает три разных результата).
Если у вас есть фильтр X
, который дает четыре результата, тогда выражение [X]
даст единственный результат, массив из четырех элементов.
Examples
jq ‘[.user,.projects[]]’ | |
Input | {«пользователь»: «стедолан», «проекты»: [«jq», «wikiflow»]} |
Output | [«stedolan», «jq», «wikiflow»] |
jq ‘[.[]|.*2]’ | |
Input | [1, 2, 3] |
Output | [2, 4, 6] |
Строительство объекта: {}
Как и JSON, {}
предназначен для создания объектов (то есть словарей или хешей), например: {"a": 42, "b": 17}
.
Если ключи «подобны идентификатору», то кавычки можно опустить, как в {a:42, b:17}
. Ключи, генерируемые выражениями, необходимо заключать в круглые скобки, например, {("a"+"b"):59}
.
Значением может быть любое выражение (хотя вам может понадобиться обернуть его в круглые скобки,если оно сложное),которое применяется к входу выражения {}(помните,что все фильтры имеют вход и выход).
{foo: .bar}
создаст объект JSON {"foo": 42}
если в качестве входных данных будет задан объект JSON {"bar":42, "baz":43}
. Вы можете использовать это для выбора определенных полей объекта: если ввод — это объект с полями «пользователь», «заголовок», «идентификатор» и «содержимое», а вам просто нужны «пользователь» и «заголовок», вы можете написать
{user: .user, title: .title}
Поскольку это очень распространено, для него существует сокращенный синтаксис: {user, title}
.
Если одно из выражений дает несколько результатов,будет создано несколько словарей.Если на входе
{"user":"stedolan","titles":["JQ Primer", "More JQ"]}
тогда выражение
{user, title: .titles[]}
даст два выхода:
{"user":"stedolan", "title": "JQ Primer"} {"user":"stedolan", "title": "More JQ"}
Заключение ключа в круглые скобки означает,что он будет оценен как выражение.С теми же входными данными,что и выше,
{(.user): .titles}
produces
{"stedolan": ["JQ Primer", "More JQ"]}
Examples
jq ‘{user,title:.titles[]}’ | |
Input | {«user»: «stedolan», «title»: [«JQ Primer», «More JQ»]} |
Output | {«user»:»stedolan», «title»: «JQ Primer»} |
{«user»: «stedolan», «title»: «Еще JQ»} |
jq ‘{(.user):.titles}’ | |
Input | {«user»: «stedolan», «title»: [«JQ Primer», «More JQ»]} |
Output | {«stedolan»: [«JQ Primer», «More JQ»]} |
Рекурсивный спуск: ..
Рекурсивно спускается .
, производя каждое значение. Это то же самое, что встроенная recurse
рекурсии с нулевым аргументом (см. Ниже). Это должно напоминать оператор XPath //
. Обратите внимание, что ..a
не работает; используйте вместо этого ..|.a
. В приведенном ниже примере мы используем ..|.a?
чтобы найти все значения ключей объекта «a» в любом объекте, найденном «ниже» .
.
Это особенно полезно в сочетании с path(EXP)
(также см. Ниже) и ?
оператор.
Example
jq ‘..|.a?’ | |
Input | [[{«a»:1}]] |
Output | 1 |
Сборка операторов и функций
Некоторые операторы jq (например, +
) делают разные вещи в зависимости от типа своих аргументов (массивы, числа и т. Д.). Однако jq никогда не выполняет неявных преобразований типов. Если вы попытаетесь добавить строку к объекту, вы получите сообщение об ошибке и никакого результата.
Обратите внимание,что все числа преобразуются в представление IEEE754 двойной точности с плавающей точкой.Арифметические и логические операторы работают с этими преобразованными двойными числами.Результаты всех таких операций также ограничены двойной точностью.
Единственным исключением из этого поведения числа является снимок исходного литерала числа.Если число,которое изначально было представлено в виде литерала,никогда не изменяется до конца программы,то оно выводится на вывод в своей оригинальной литеральной форме.Это также включает случаи,когда исходный литерал будет усечен при преобразовании в число с плавающей точкой двойной точности IEEE754.
Addition: +
Оператор +
берет два фильтра, применяет их к одному и тому же входу и складывает результаты вместе. Что означает «добавление», зависит от задействованных типов:
- Числа складываются обычной арифметикой.
- Массивы добавляются путем объединения в больший массив.
- Строки добавляются путем объединения в более крупную строку.
- Объекты добавляются путем слияния, то есть путем вставки всех пар ключ-значение из обоих объектов в один комбинированный объект. Если оба объекта содержат значение для одного и того же ключа, выигрывает объект справа от
+
. (Для рекурсивного слияния используйте оператор*
.)
null
может быть добавлен к любому значению и возвращает другое значение без изменений.
Examples
jq ‘.a+1’ | |
Input | {«a»: 7} |
Output | 8 |
jq ‘.a+.b’ | |
Input | {«a»: [1,2], «b»: [3,4]} |
Output | [1,2,3,4] |
jq ‘.a+null’ | |
Input | {«a»: 1} |
Output | 1 |
jq ‘.a+1’ | |
Input | {} |
Output | 1 |
jq ‘{a:1}+{b:2}+{c:3}+{a:42}’ | |
Input | null |
Output | {«a»: 42, «b»: 2, «c»: 3} |
Subtraction: -
Помимо обычного арифметического вычитания чисел, оператор -
может использоваться с массивами для удаления всех вхождений элементов второго массива из первого массива.
Examples
jq ‘4-.a’ | |
Input | {«a»:3} |
Output | 1 |
jq ‘.-[«xml»,»yaml»]» | |
Input | [«xml», «yaml», «json»] |
Output | [«json»] |
Умножение, деление, по модулю: *
, /
и %
Эти инфиксные операторы ведут себя должным образом при наличии двух чисел. Деление на ноль вызывает ошибку. x % y
вычисляет x по модулю y.
Умножение строки на число приводит к многократному объединению этой строки. "x" * 0
дает ноль .
Деление строки на другую делит первую строку,используя вторую в качестве разделителей.
Умножение двух объектов приводит к их рекурсивному слиянию:это работает как сложение,но если оба объекта содержат значение для одного и того же ключа,а значения являются объектами,то они объединяются по одной и той же стратегии.
Examples
jq ’10/.*3′ | |
Input | 5 |
Output | 6 |
jq ‘./»,»‘ | |
Input | «а, б, в, г, д» |
Output | [«a»,»b,c,d»,»e»] |
jq ‘{‘k’:{«a»:1,»b»:2}}*{«k»:{«a»:0,»c»:3}}’ | |
Input | null |
Output | {«k»: {«a»: 0, «b»: 2, «c»: 3}} |
jq ‘.[]| (1/.)?’ | |
Input | [1,0,-1] |
Output | 1 |
-1 |
length
Встроенная функция length
получает длину различных типов значений:
- Длина строки — это количество содержащихся в ней кодовых точек Unicode (которое будет таким же, как длина в байтах в кодировке JSON, если это чистый ASCII).
- Длина массива — это количество элементов.
- Длина объекта — это количество пар ключ-значение.
- Длина нуля равна нулю.
Example
jq ‘.[]| length’ | |
Input | [[1,2], «строка», {«a»: 2}, ноль] |
Output | 2 |
6 | |
1 | |
0 |
utf8bytelength
utf8bytelength
функция utf8bytelength выводит количество байтов, используемых для кодирования строки в UTF-8.
Example
jq ‘utf8bytelength’ | |
Input | «u03bc» |
Output | 2 |
keys
, keys_unsorted
Встроенные функциональные keys
, когда им задан объект, возвращают его ключи в массиве.
Ключи сортируются «по алфавиту»,в порядке кодовых точек Юникода.Это не тот порядок,который имеет смысл в каком-либо конкретном языке,но вы можете рассчитывать на то,что он будет одинаковым для любых двух объектов с одинаковым набором ключей,независимо от настроек локали.
Когда keys
передается массив, он возвращает действительные индексы для этого массива: целые числа от 0 до length-1.
Функция keys_unsorted
аналогична функциям keys
, но если ввод является объектом, то ключи не будут отсортированы, вместо этого ключи будут примерно в порядке вставки.
Examples
jq ‘keys’ | |
Input | {«abc»: 1, «abcd»: 2, «Foo»: 3} |
Output | [«Foo», «abc», «abcd»] |
jq ‘keys’ | |
Input | [42,3,35] |
Output | [0,1,2] |
has(key)
Встроенная функция возвращает, has
ли входной объект заданный ключ или входной массив имеет элемент по заданному индексу.
has($key)
имеет тот же эффект, что и проверка, является ли $key
членом массива, возвращаемого keys
, хотя has
будет быстрее.
Examples
jq ‘map(has(«foo»))’ | |
Input | [{«foo»: 42}, {}] |
Output | [true, false] |
jq ‘map(has(2))’ | |
Input | [[0,1], [«a»,»b»,»c»]] |
Output | [false, true] |
in
Встроенная функция in
возвращает независимо от того, находится ли входной ключ в данном объекте или входной индекс соответствует элементу в данном массиве. По сути, это перевернутая версия has
.
Examples
jq ‘.[]| in({«foo»:42})’ | |
Input | [«foo», «bar»] |
Output | true |
false |
jq ‘map(in([0,1]))’ | |
Input | [2, 0] |
Output | [false, true] |
map(x)
, map_values(x)
Для любого фильтра x
, map(x)
будет работать этот фильтр для каждого элемента входного массива, и возвращает выходы в новом массиве. map(.+1)
будет увеличивать каждый элемент массива чисел.
Точно так же map_values(x)
будет запускать этот фильтр для каждого элемента, но он вернет объект, когда объект будет передан.
map(x)
эквивалентен [.[] | x]
. Фактически, это то, как это определяется. Точно так же, map_values(x)
определяется как .[] |= x
.
Examples
jq ‘map(.+1)’ | |
Input | [1,2,3] |
Output | [2,3,4] |
jq ‘map_values(.+1)’ | |
Input | {«a»: 1, «b»: 2, «c»: 3} |
Output | {«a»: 2, «b»: 3, «c»: 4} |
path(path_expression)
Выводит представление массива данного выражения пути в формате .
. Выходы представляют собой массивы строк (ключей объектов) и / или чисел (индексы массивов).
Выражения пути — это выражения jq, такие как .a
, но также .[]
. Есть два типа выражений пути: те, которые могут точно соответствовать, и те, которые не могут. Например, .a.b.c
— это выражение пути точного совпадения, а .a[].b
— нет.
path(exact_path_expression)
создаст представление массива выражения пути, даже если оно не существует в .
, если .
является null
массивом или объектом.
path(pattern)
создаст массивные представления путей, соответствующих pattern
если пути существуют в .
.
Обратите внимание, что выражения пути не отличаются от обычных выражений. Выражение path(..|select(type=="boolean"))
выводит все пути к логическим значениям в .
, и только этими путями.
Examples
jq ‘path(.a[0].b)’ | |
Input | null |
Output | [«a»,0,»b»] |
jq ‘[path(..)]’ | |
Input | {«a»:[{«b»:1}]} |
Output | [[],[«a»],[«a»,0],[«a»,0,»b»]] |
del(path_expression)
Встроенная функция del
удаляет ключ и соответствующее ему значение из объекта.
Examples
jq ‘del(.foo)’ | |
Input | {«foo»: 42, «bar»: 9001, «baz»: 42} |
Output | {«bar»: 9001, «baz»: 42} |
jq ‘del(.[1,2])’ | |
Input | [«фу», «бар», «баз»] |
Output | [«foo»] |
getpath(PATHS)
getpath
функция getpath выводит значения в формате .
можно найти на каждом пути в PATHS
.
Examples
jq ‘getpath([«a»,»b»])’ | |
Input | null |
Output | null |
jq ‘[getpath([«a»,»b»],[«a»,»c»])]» | |
Input | {«a»:{«b»:0, «c»:1}} |
Output | [0, 1] |
setpath(PATHS; VALUE)
setpath
функция setpath устанавливает PATHS
в .
в VALUE
.
Examples
jq ‘setpath([«a»,»b»];1)’ | |
Input | null |
Output | {«а»: {«б»: 1}} |
jq ‘setpath([«a»,»b»];1)’ | |
Input | {«a»:{«b»:0}} |
Output | {«а»: {«б»: 1}} |
jq ‘setpath([0,»a»];1)’ | |
Input | null |
Output | [{«a»:1}] |
delpaths(PATHS)
delpaths
функция delpaths устанавливает PATHS
в .
. PATHS
должен быть массивом путей, где каждый путь представляет собой массив строк и чисел.
Example
jq ‘delpaths([[«a»,»b»]])’ | |
Input | {«a»:{«b»:1},»x»:{«y»:2}} |
Output | {«a»:{},»x»:{«y»:2}} |
to_entries
, from_entries
, with_entries
Эти функции выполняют преобразование между объектом и массивом пар ключ-значение. Если to_entries
передается объекту, то для каждой записи k: v
на входе выходной массив включает {"key": k, "value": v}
.
from_entries
выполняет противоположное преобразование, а with_entries(foo)
является сокращением для to_entries | map(foo) | from_entries
, полезно для выполнения некоторых операций со всеми ключами и значениями объекта. from_entries
принимает ключ, ключ, имя, имя, значение и значение в качестве ключей.
Examples
jq ‘to_entries’ | |
Input | {«a»: 1, «b»: 2} |
Output | [{«ключ»: «a», «значение»: 1}, {«ключ»: «b», «значение»: 2}] |
jq ‘from_entries’ | |
Input | [{«ключ»: «a», «значение»: 1}, {«ключ»: «b», «значение»: 2}] |
Output | {«a»: 1, «b»: 2} |
jq ‘with_entries(.key |=»KEY_»+.)’ | |
Input | {«a»: 1, «b»: 2} |
Output | {«KEY_a»: 1, «KEY_b»: 2} |
select(boolean_expression)
Функция select(foo)
производит свой ввод без изменений, если foo
возвращает true для этого ввода, и не производит никакого вывода в противном случае.
Это полезно для фильтрации списков: [1,2,3] | map(select(. >= 2))
даст вам [2,3]
.
Examples
jq ‘карта (выберите (.> = 2))’ | |
Input | [1,5,3,0,7] |
Output | [5,3,7] |
jq ‘.[]| select(.id ==»second»)’ | |
Input | [{«id»: «первый», «val»: 1}, {«id»: «второй», «val»: 2}] |
Output | {«id»: «second», «val»: 2} |
arrays
, objects
, iterables
, booleans
, numbers
, normals
, finites
, strings
, nulls
, values
, scalars
Эти встроенные модули выбирают только те входы,которые являются массивами,объектами,итерациями (массивами или объектами),булевыми числами,числами,нормальными числами,конечными числами,строками,нулевыми,ненулевыми значениями и неитерациями,соответственно.
Example
jq ‘.[]|numbers’ | |
Input | [[],{},1,»foo»,null,true,false] |
Output | 1 |
empty
empty
возвращает результатов. Вовсе нет. Даже не null
.
Это полезно в некоторых случаях.Вы узнаете,если она вам понадобится 🙂
Examples
jq ‘1,пусто,2’ | |
Input | null |
Output | 1 |
2 |
jq ‘[1,2,empty,3]’ | |
Input | null |
Output | [1,2,3] |
error(message)
Выдает ошибку, точно так же, как .a
применяется к значениям, отличным от null и объектов, но с заданным сообщением в качестве значения ошибки. Ошибки можно отловить с помощью try / catch; см. ниже.
halt
Останавливает программу jq без дальнейших выходов. jq выйдет со статусом выхода 0
.
halt_error
, halt_error(exit_code)
Останавливает программу jq без дальнейших выходов. Ввод будет напечатан на stderr
как необработанный вывод (т. Е. Строки не будут иметь двойных кавычек) без оформления, даже без символа новой строки.
Данный exit_code
(недобросовестный 5
) будет статус выхода JQ в.
Например, "Error: somthing went wrongn"|halt_error(1)
.
$__loc__
Создает объект с ключом «файл» и ключом «строка» с именем файла и номером строки, где встречается $__loc__
, в качестве значений.
Example
jq ‘try error(«($__loc__)»)catch .’ | |
Input | null |
Output | «{»file»:»<top-level>»,»line»:1}» |
paths
, paths(node_filter)
, leaf_paths
paths
выводит пути ко всем элементам на входе (за исключением того, что он не выводит пустой список, представляющий сам.).
paths(f)
выводит пути к любым значениям, для которых f
истинно. То есть paths(numbers)
выводит пути ко всем числовым значениям.
leaf_paths
— это псевдоним paths(scalars)
; leaf_paths
является устаревшим и будет удален в следующей версии.
Examples
jq ‘[paths]’ | |
Input | [1,[[],{«a»:2}]] |
Output | [[0],[1],[1,0],[1,1],[1,1,»a»]] |
jq ‘[paths(scalars)]’ | |
Input | [1,[[],{«a»:2}]] |
Output | [[0],[1,1,»a»]] |
add
Фильтр add
принимает на входе массив и производит на выходе элементы массива, сложенные вместе. Это может означать суммирование, сцепление или объединение в зависимости от типов элементов входного массива — правила такие же, как и для оператора +
(описанного выше).
Если ввод — пустой массив, add
возвращает null
.
Examples
jq ‘add’ | |
Input | [«a»,»b»,»c»] |
Output | «abc» |
jq ‘add’ | |
Input | [1, 2, 3] |
Output | 6 |
jq ‘add’ | |
Input | [] |
Output | null |
any
, any(condition)
, any(generator; condition)
Фильтр any
принимает в качестве входных данных массив логических значений и выдает на выходе значение « true
если какой-либо из элементов массива является true
.
Если ввод — пустой массив, any
возвращает false
.
Форма any(condition)
применяет данное условие к элементам входного массива.
Форма any(generator; condition)
применяет данное условие ко всем выходам данного генератора.
Examples
jq ‘any’ | |
Input | [true, false] |
Output | true |
jq ‘any’ | |
Input | [false, false] |
Output | false |
jq ‘any’ | |
Input | [] |
Output | false |
all
, all(condition)
, all(generator; condition)
Фильтр all
принимает в качестве входных данных массив булевых значений, и производит true
в качестве выходного сигнала , если все элементы массива являются true
.
Форма all(condition)
применяет данное условие к элементам входного массива.
Форма all(generator; condition)
применяет данное условие ко всем выходам данного генератора.
Если вход является пустым массивом, all
возвращает true
.
Examples
jq ‘all’ | |
Input | [true, false] |
Output | false |
jq ‘all’ | |
Input | [true, true] |
Output | true |
jq ‘all’ | |
Input | [] |
Output | true |
flatten
, flatten(depth)
Фильтр flatten
принимает в качестве входных данных массив вложенных массивов и создает плоский массив, в котором все массивы внутри исходного массива рекурсивно заменены их значениями. Вы можете передать ему аргумент, чтобы указать, сколько уровней вложенности нужно сгладить.
flatten(2)
похож на flatten
, но углубляется только на два уровня.
Examples
jq ‘flatten’ | |
Input | [1, [2], [[3]]] |
Output | [1, 2, 3] |
jq ‘flatten(1)’ | |
Input | [1, [2], [[3]]] |
Output | [1, 2, [3]] |
jq ‘flatten’ | |
Input | [[]] |
Output | [] |
jq ‘flatten’ | |
Input | [{«foo»: «bar»}, [{«foo»: «baz»}]] |
Output | [{«foo»: «bar»}, {«foo»: «baz»}] |
range(upto)
, range(from;upto)
range(from;upto;by)
Функция range
создает диапазон чисел. range(4;10)
производит 6 чисел от 4 (включительно) до 10 (исключая). Цифры выдаются как отдельные выходы. Используйте [range(4;10)]
чтобы получить диапазон в виде массива.
Форма с одним аргументом генерирует числа от 0 до заданного числа с инкрементом 1.
Две формы аргумента генерирует числа от from
до upto
с шагом 1.
Форма с тремя аргументами генерирует числа from
до upto
с приращением by
.
Examples
jq ‘range(2;4)’ | |
Input | null |
Output | 2 |
3 |
jq ‘[range(2;4)]’ | |
Input | null |
Output | [2,3] |
jq ‘[range(4)]’ | |
Input | null |
Output | [0,1,2,3] |
jq ‘[range(0;10;3)]’ | |
Input | null |
Output | [0,3,6,9] |
jq ‘[range(0;10;-1)]’ | |
Input | null |
Output | [] |
jq ‘[range(0;-5;-1)]’ | |
Input | null |
Output | [0,-1,-2,-3,-4] |
floor
Функция floor
возвращает нижний предел своего числового ввода.
Example
jq ‘floor’ | |
Input | 3.14159 |
Output | 3 |
sqrt
Функция sqrt
возвращает квадратный корень из входных числовых значений.
Example
jq ‘sqrt’ | |
Input | 9 |
Output | 3 |
tonumber
Функция tonumber
анализирует свой ввод как число. Он преобразует правильно отформатированные строки в их числовой эквивалент, оставит числа в покое и выдаст ошибку для всех остальных входных данных.
Example
jq ‘.[]| tonumber’ | |
Input | [1, «1»] |
Output | 1 |
1 |
tostring
Функция tostring
печатает ввод в виде строки. Строки остаются без изменений, а все остальные значения кодируются в формате JSON.
Example
jq ‘.[]| tostring’ | |
Input | [1, «1», [1]] |
Output | «1» |
«1» | |
«[1]» |
type
Функция type
возвращает тип своего аргумента в виде строки, которая может быть пустой, логической, числом, строкой, массивом или объектом.
Example
jq ‘map(type)’ | |
Input | [0, ложь, [], {}, ноль, «привет»] |
Output | [«число», «логическое», «массив», «объект», «ноль», «строка»] |
infinite
, nan
, isinfinite
, isnan
, isfinite
, isnormal
Некоторые арифметические операции могут давать бесконечные значения, а не числа (NaN). isinfinite
встроенный возвращает true
, если его вход бесконечен. isnan
встроенный возвращает true
, если его ввод является NaN. infinite
встроенный возвращает положительное бесконечное значение. nan
встроенный возвращает NaN. isnormal
встроенный возвращает истину , если ее вход нормальный номер.
Обратите внимание,что деление на ноль приводит к ошибке.
В настоящее время большинство арифметических операций,работающих с бесконечностью,NaN и субнормалями,не вызывают ошибок.
Examples
jq ‘. [] | (бесконечное *.) <0 ‘ | |
Input | [-1, 1] |
Output | true |
false |
jq ‘infinite,nan | type’ | |
Input | null |
Output | «number» |
«number» |
sort, sort_by(path_expression)
Функции sort
сортируют свой ввод, который должен быть массивом. Значения отсортированы в следующем порядке:
null
false
true
- numbers
- строки,в алфавитном порядке (по значению кодовой точки Юникода)
- массивы,в лексическом порядке
- objects
Упорядочение объектов немного сложнее:сначала они сравниваются путем сравнения их наборов ключей (как массивы в отсортированном порядке),и если их ключи равны,то значения сравниваются по ключу.
sort
может использоваться для сортировки по определенному полю объекта или путем применения любого фильтра jq.
sort_by(foo)
сравнивает два элемента, сравнивая результат foo
для каждого элемента.
Examples
jq ‘sort’ | |
Input | [8,3,null,6] |
Output | [null,3,6,8] |
jq ‘sort_by(.foo)’ | |
Input | [{«foo»:4, «bar»:10}, {«foo»:3, «bar»:100}, {«foo»:2, «bar»:1}] |
Output | [{«foo»:2, «bar»:1}, {«foo»:3, «bar»:100}, {«foo»:4, «bar»:10}] |
group_by(path_expression)
group_by(.foo)
принимает в качестве входных данных массив, группирует элементы, имеющие одинаковое поле .foo
, в отдельные массивы и производит все эти массивы как элементы большего массива, отсортированные по значению поля .foo
.
Вместо .foo
можно использовать любое выражение jq, а не только доступ к полю . Порядок сортировки такой же, как описано в функции sort
выше.
Example
jq ‘group_by(.foo)’ | |
Input | [{«foo»:1, «bar»:10}, {«foo»:3, «bar»:100}, {«foo»:1, «bar»:1}] |
Output | [[{«foo»:1, «bar»:10}, {«foo»:1, «bar»:1}], [{«foo»:3, «bar»:100}]] |
min
, max
, min_by(path_exp)
, max_by(path_exp)
Найдите минимальный или максимальный элемент входного массива.
Функции min_by(path_exp)
и max_by(path_exp)
позволяют указать конкретное поле или свойство для исследования, например min_by(.foo)
находит объект с наименьшим полем foo
.
Examples
jq ‘min’ | |
Input | [5,4,2,7] |
Output | 2 |
jq ‘max_by(.foo)’ | |
Input | [{«foo»:1, «bar»:14}, {«foo»:2, «bar»:3}] |
Output | {«foo»:2, «bar»:3} |
unique
, unique_by(path_exp)
unique
функция принимает в качестве входных данных массива и производит массив из одних и тех же элементов, в отсортированном порядке, с дубликатами удалены.
Функция unique_by(path_exp)
сохранит только один элемент для каждого значения, полученного применением аргумента. Думайте об этом как о создании массива, взяв по одному элементу из каждой группы, созданной group
.
Examples
jq ‘unique’ | |
Input | [1,2,5,3,5,3,1,3] |
Output | [1,2,3,5] |
jq ‘unique_by(.foo)’ | |
Input | [{«foo»: 1, «bar»: 2}, {«foo»: 1, «bar»: 3}, {«foo»: 4, «bar»: 5}] |
Output | [{«foo»: 1, «bar»: 2}, {«foo»: 4, «bar»: 5}] |
jq ‘unique_by(length)’ | |
Input | [«кусочек», «бекон», «котенок», «цикада», «спаржа»] |
Output | [«бекон», «кусочки», «спаржа»] |
reverse
Эта функция инвертирует массив.
Example
jq ‘reverse’ | |
Input | [1,2,3,4] |
Output | [4,3,2,1] |
contains(element)
Фильтр contains(b)
выдаст значение true, если b полностью содержится во входных данных. Строка B содержится в строке A, если B является подстрокой A. Массив B содержится в массиве A, если все элементы в B содержатся в любом элементе в A. Объект B содержится в объекте A, если все значения в B содержатся в значении в A с тем же ключом. Предполагается, что все другие типы содержатся друг в друге, если они равны.
Examples
jq ‘contains(«bar»)’ | |
Input | «foobar» |
Output | true |
jq ‘contains([«baz»,»bar»])’ | |
Input | [«foobar», «foobaz», «blarp»] |
Output | true |
jq ‘contains([«bazzzzz»,»bar»])’ | |
Input | [«foobar», «foobaz», «blarp»] |
Output | false |
jq ‘contains({foo:12,bar:[{barp:12}]})’ | |
Input | {«foo»: 12, «bar»:[1,2,{«barp»:12, «blip»:13}]} |
Output | true |
jq ‘contains({foo:12,bar:[{barp:15}]})’ | |
Input | {«foo»: 12, «bar»:[1,2,{«barp»:12, «blip»:13}]} |
Output | false |
indices(s)
Выводит массив, содержащий индексы в .
где встречается s
. Вход может быть массивом, и в этом случае, если s
является массивом, тогда выходными индексами будут те, в которых все элементы находятся .
соответствуют тем из s
.
Examples
jq ‘indices(«,»)’ | |
Input | «a,b, cd, efg, hijk» |
Output | [3,7,12] |
jq ‘indices(1)’ | |
Input | [0,1,2,1,3,1,4] |
Output | [1,3,5] |
jq ‘indices([1,2])’ | |
Input | [0,1,2,3,1,4,2,5,1,2,6,7] |
Output | [1,8] |
index(s)
, rindex(s)
Выводит индекс первого ( index
) или последнего ( rindex
) вхождения s
во входных данных.
Examples
jq ‘index(«,»)’ | |
Input | «a,b, cd, efg, hijk» |
Output | 3 |
jq ‘rindex(«,»)’ | |
Input | «a,b, cd, efg, hijk» |
Output | 12 |
inside
Фильтр inside(b)
даст истину, если вход полностью содержится в b. По сути, это перевернутая версия файла contains
.
Examples
jq ‘inside(«foobar»)’ | |
Input | «bar» |
Output | true |
jq ‘inside([«foobar»,»foobaz»,»blarp»])’ | |
Input | [«baz», «bar»] |
Output | true |
jq ‘inside([«foobar»,»foobaz»,»blarp»])’ | |
Input | [«bazzzzz», «bar»] |
Output | false |
jq ‘inside({«foo»:12,»bar»:[1,2,{«barp»:12,»blip»:13}]})’ | |
Input | {«foo»: 12, «bar»: [{«barp»: 12}]} |
Output | true |
jq ‘inside({«foo»:12,»bar»:[1,2,{«barp»:12,»blip»:13}]})’ | |
Input | {«foo»: 12, «bar»: [{«barp»: 15}]} |
Output | false |
startswith(str)
Выдает true
если. начинается с заданного строкового аргумента.
Example
jq ‘[.[]|startswith(«foo»)]’ | |
Input | [«fo», «foo», «barfoo», «foobar», «barfoob»] |
Output | [ложь, истина, ложь, истина, ложь] |
endswith(str)
Выдает true
если. заканчивается заданным строковым аргументом.
Example
jq ‘[.[]|endswith(«foo»)]’ | |
Input | [«foobar», «barfoo»] |
Output | [false, true] |
combinations
, combinations(n)
Выводит все комбинации элементов массивов во входном массиве. Если задан аргумент n
, он выводит все комбинации n
повторений входного массива.
Examples
jq ‘combinations’ | |
Input | [[1,2], [3, 4]] |
Output | [1, 3] |
[1, 4] | |
[2, 3] | |
[2, 4] |
jq ‘combinations(2)’ | |
Input | [0, 1] |
Output | [0, 0] |
[0, 1] | |
[1, 0] | |
[1, 1] |
ltrimstr(str)
Выводит входные данные с удаленной заданной префиксной строкой,если они начинаются с нее.
Example
jq ‘[.[]|ltrimstr(«foo»)]’ | |
Input | [«fo», «foo», «barfoo», «foobar», «afoo»] |
Output | [«fo»,»»,»barfoo»,»bar»,»afoo»] |
rtrimstr(str)
Выводит входные данные с удаленной заданной суффиксной строкой,если они заканчиваются ею.
Example
jq ‘[.[]|rtrimstr(«foo»)]’ | |
Input | [«fo», «foo», «barfoo», «foobar», «foob»] |
Output | [«fo»,»»,»bar»,»foobar»,»foob»] |
explode
Преобразует входную строку в массив номеров кодовых точек строки.
Example
jq ‘explode’ | |
Input | «foobar» |
Output | [102,111,111,98,97,114] |
implode
Обратное значение слова «взорваться».
Example
jq ‘implode’ | |
Input | [65, 66, 67] |
Output | «ABC» |
split(str)
Разделяет входную строку по аргументу разделителя.
Example
jq ‘split(«,»)’ | |
Input | «а, б, в, г, д,» |
Output | [«a»,»b,c,d»,»e»,»»] |
join(str)
Присоединяется к массиву элементов, заданных как входные, с использованием аргумента в качестве разделителя. Это противоположность split
: выполнение split("foo") | join("foo")
над любой входной строкой возвращает указанную входную строку.
Числа и булевы в исходных данных преобразуются в строки.Нулевые значения рассматриваются как пустые строки.Массивы и объекты во входных данных не поддерживаются.
Examples
jq ‘join(«,»)’ | |
Input | [«a»,»b,c,d»,»e»] |
Output | «а, б, в, г, д» |
jq ‘join(» «)’ | |
Input | [«a»,1,2.3,true,null,false] |
Output | «a 1 2.3 истина ложь» |
ascii_downcase
, ascii_upcase
Выдает копию входной строки с алфавитными символами (a-z и A-Z),преобразованными в указанный регистр.
while(cond; update)
Функция while(cond; update)
позволяет многократно применять обновление к файлам .
пока cond
не станет ложным.
Обратите внимание, что while(cond; update)
внутренне определяется как рекурсивная функция jq. Рекурсивные вызовы внутри while
не будут потреблять дополнительную память, если update
производит не более одного вывода для каждого ввода. См. Дополнительные темы ниже.
Example
jq ‘[в то время как (. <100;. * 2)]’ | |
Input | 1 |
Output | [1,2,4,8,16,32,64] |
until(cond; next)
Функция until(cond; next)
позволяет многократно применять выражение next
, первоначально к .
затем на собственный выход, пока cond
не станет истинным. Например, это можно использовать для реализации факториальной функции (см. Ниже).
Обратите внимание, что until(cond; next)
внутренне определяется как рекурсивная функция jq. Рекурсивные вызовы в until()
не будут потреблять дополнительную память, если next
производит не более одного вывода для каждого ввода. См. Дополнительные темы ниже.
Example
jq ‘[., 1] | до (. [0] <1; [. [0] — 1,. [1] *. [0]]) |. [1]’ | |
Input | 4 |
Output | 24 |
recurse(f)
, recurse
, recurse(f; condition)
, recurse_down
Функция recurse(f)
позволяет выполнять поиск по рекурсивной структуре и извлекать интересные данные со всех уровней. Предположим, ваш ввод представляет файловую систему:
{"name": "/", "children": [ {"name": "/bin", "children": [ {"name": "/bin/ls", "children": []}, {"name": "/bin/sh", "children": []}]}, {"name": "/home", "children": [ {"name": "/home/stephen", "children": [ {"name": "/home/stephen/jq", "children": []}]}]}]}
Теперь предположим, что вы хотите извлечь все существующие имена файлов. Вам нужно получить .name
, .children[].name
.children[].children[].name
, .children []. Children []. Name и так далее. Вы можете сделать это с помощью:
recurse(.children[]) | .name
При вызове без аргумента recurse
эквивалентна recurse(.[]?)
.
recurse(f)
идентичен recurse(f; . != null)
и может использоваться, не беспокоясь о глубине рекурсии.
recurse(f; condition)
— это генератор, который начинается с испускания. а затем по очереди излучает. | f,. | f | f,. | f | f | f, … до тех пор, пока вычисленное значение удовлетворяет условию. Например, чтобы сгенерировать все целые числа, по крайней мере в принципе, можно было бы написать recurse(.+1; true)
.
По устаревшим причинам recurse_down
существует как псевдоним для вызова recurse
без аргументов. Этот псевдоним считается устаревшим и будет удален в следующем основном выпуске.
Рекурсивные вызовы в recurse
не будут потреблять дополнительную память, если f
производит не более одного вывода для каждого ввода.
Examples
jq ‘recurse(.foo[])’ | |
Input | {«foo»:[{«foo»: []}, {«foo»:[{«foo»:[]}]}]} |
Output | {«foo»:[{«foo»:[]},{«foo»:[{«foo»:[]}]}]} |
{«foo»:[]} | |
{«foo»:[{«foo»:[]}]} | |
{«foo»:[]} |
jq ‘recurse’ | |
Input | {«a»:0,»b»:[1]} |
Output | {«a»:0,»b»:[1]} |
0 | |
[1] | |
1 |
jq ‘рекурсивный (. *.;. <20)’ | |
Input | 2 |
Output | 2 |
4 | |
16 |
walk(f)
Функция walk(f)
рекурсивно применяет f к каждому компоненту входной сущности. Когда встречается массив, f сначала применяется к его элементам, а затем к самому массиву; при обнаружении объекта f сначала применяется ко всем значениям, а затем к объекту. На практике f обычно проверяет тип своего ввода, как показано в следующих примерах. Первый пример подчеркивает полезность обработки элементов массива массивов перед обработкой самого массива. Второй пример показывает, как можно рассмотреть возможность изменения всех ключей всех объектов на входе.
Examples
jq ‘walk(if type ==»array» then sort else.end)’ | |
Input | [[4, 1, 7], [8, 5, 2], [3, 6, 9]] |
Output | [[1,4,7],[2,5,8],[3,6,9]] |
jq ‘walk(if type ==»object» then with_entries(.key |=sub(«^_+»;»»))else.end )» | |
Input | [ { «_a»: { «__b»: 2 } } ] |
Output | [{«a»:{«b»:2}}] |
$ENV
, env
$ENV
— это объект, представляющий переменные среды, установленные при запуске программы jq.
env
выводит объект, представляющий текущую среду jq.
На данный момент не существует встроенного модуля для установки переменных окружения.
Examples
jq ‘$ENV.PAGER’ | |
Input | null |
Output | «less» |
jq ‘env.PAGER’ | |
Input | null |
Output | «less» |
transpose
Транспонировать возможно неровную матрицу (массив массивов).Строки заполняются нулями,чтобы результат всегда был прямоугольным.
Example
jq ‘transpose’ | |
Input | [[1], [2,3]] |
Output | [[1,2],[null,3]] |
bsearch(x)
bsearch(x)выполняет бинарный поиск x во входном массиве.Если входной массив отсортирован и содержит x,то bsearch(x)вернет его индекс в массиве;в противном случае,если массив отсортирован,он вернет (-1-ix),где ix-точка вставки,такая,что массив все еще будет отсортирован после вставки x в ix.Если массив не отсортирован,bsearch(x)вернет целое число,которое,вероятно,не представляет интереса.
Examples
jq ‘bsearch(0)’ | |
Input | [0,1] |
Output | 0 |
jq ‘bsearch(0)’ | |
Input | [1,2,3] |
Output | -1 |
jq ‘bsearch (4) as $ ix | если $ ix <0, то. [- (1 + $ ix)] = 4 else. конец’ | |
Input | [1,2,3] |
Output | [1,2,3,4] |
Строковая интерполяция — (foo)
Внутри строки можно поместить выражение в родительских папках после обратной косой черты.Все,что возвращает выражение,будет интерполировано в строку.
Example
jq ‘»Вход был (.),что на единицу меньше,чем (.+1)» ‘ | |
Input | 42 |
Output | «Введено 42, что на единицу меньше 43» |
Преобразование в/из JSON
В tojson
и fromjson
встроенных функций дамп значения как тексты JSON или синтаксический анализ текстов JSON в значение, соответственно. Встроенная функция tojson отличается от tostring тем, что tostring возвращает строки без изменений, а tojson кодирует строки как строки JSON.
Examples
jq ‘[.[]|tostring]’ | |
Input | [1, «фу», [«фу»]] |
Output | [«1″,»foo»,»[»foo»]»] |
jq ‘[.[]|tojson]’ | |
Input | [1, «фу», [«фу»]] |
Output | [«1″,»»foo»»,»[»foo»]»] |
jq ‘[.[]|tojson|fromjson]’ | |
Input | [1, «фу», [«фу»]] |
Output | [1,»foo»,[«foo»]] |
Форматирование строк и экранирование
@foo
синтаксис используется для форматирования и эвакуационных строк, что полезно для построения URL, документы на языке , как HTML или XML, и так далее. @foo
может использоваться сам по себе как фильтр, возможные варианты экранирования:
@text
:
Вызывает tostring
, подробности см. В этой функции.
@json
:
Сериализует входные данные в формате JSON.
@html
:
Применяется HTML / XML побега, путем отображения символов <>&'"
их эквиваленты сущностей <
, >
, &
, '
, "
.
@uri
:
Применяет процентное кодирование, сопоставляя все зарезервированные символы URI последовательности %XX
.
@csv
:
Входные данные должны быть массивом,и они отображаются как CSV с двойными кавычками для строк,и кавычки экранируются при повторении.
@tsv
:
Входными данными должен быть массив, и он отображается как TSV (значения, разделенные табуляцией). Каждый входной массив будет напечатан как одна строка. Поля разделены одной табуляцией (ascii 0x09
). Входные символы перевод строки (ascii 0x0a
), возврат каретки (ascii 0x0d
), табуляция (ascii 0x09
) и обратная косая черта (ascii 0x5c
) будут выводиться как escape-последовательности n
, r
, t
, \
соответственно.
@sh
:
Входные данные приводятся к виду,пригодному для использования в командной строке оболочки POSIX.Если входные данные являются массивом,выходными данными будет серия строк,разделенных пробелами.
@base64
:
Входные данные преобразуются в base64,как указано в RFC 4648.
@base64d
:
Обратное @base64
, вход декодируется , как определен RFC 4648. Примечание : Если декодированная строка не UTF-8, результаты не определены.
Этот синтаксис можно удобно комбинировать со строковой интерполяцией. Вы можете следовать за токеном @foo
с помощью строкового литерала. Содержимое строкового литерала не экранируется. Однако все интерполяции, сделанные внутри этого строкового литерала, будут экранированы. Например,
@uri "https://www.google.com/search?q=(.search)"
выдаст следующий результат для ввода {"search":"what is jq?"}
:
"https://www.google.com/search?q=what%20is%20jq%3F"
Обратите внимание,что косые черты,вопросительный знак и т.д.в URL не экранируются,поскольку они были частью строкового литерала.
Examples
jq ‘@html’ | |
Input | «Это работает, если x <y» |
Output | «Это работает, если x & lt; y» |
jq ‘@sh «echo (.)»‘ | |
Input | «O’Hara’s Ale» |
Output | «echo ‘O’\»Hara’\»s Ale’» |
jq ‘@base64’ | |
Input | «Это сообщение» |
Output | «VGhpcyBpcyBhIG1lc3NhZ2U=» |
jq ‘@base64d’ | |
Input | «VGhpcyBpcyBhIG1lc3NhZ2U=» |
Output | «Это сообщение» |
Dates
jq предоставляет некоторые базовые функции работы с датами,с некоторыми высокоуровневыми и низкоуровневыми встроенными модулями.Во всех случаях эти встроенные модули работают исключительно со временем в UTC.
fromdateiso8601
встроенный разбирает DateTimes в формате ISO 8601 на число секунд с эпохи Unix (1970-01-01T00: 00: 00Z). todateiso8601
встроенный делает обратное.
fromdate
встроенной разбирает даты — времени строки. В настоящее время fromdate
поддерживает только строки даты и времени ISO 8601, но в будущем он попытается анализировать строки даты и времени в других форматах.
todate
встроенный псевдоним для todateiso8601
.
now
встроенные выходы текущее время в секундах с начала эпохи Unix.
Также предоставляются низкоуровневые интерфейсы jq для функций времени библиотеки C: strptime
, strftime
, strflocaltime
, mktime
, gmtime
и localtime
. Обратитесь к документации операционной системы вашего хоста за строками формата, используемыми strptime
и strftime
. Примечание: это не обязательно стабильные интерфейсы в jq, особенно в том, что касается их функций локализации.
gmtime
встроенный потребляет количество секунд с начала эпохи Unix и выводит «разбивка времени» Представление Greenwhich Meridian время как массив чисел , представляющих (в указанном порядке): год, месяц ( начиная с нуля), на следующий день числа месяца (на основе единицы), часа дня, минуты часа, секунды минуты, дня недели и дня года — все на основе единицы, если не указано иное. Номер дня недели может быть неправильным в некоторых системах для дат до 1 марта 1900 года или после 31 декабря 2099 года.
localtime
встроенной работает как gmtime
встроенной команды, но с использованием локальной установки временной зоны.
mktime
встроенный съедает « с разбивкой времени» представлений отображения времени по gmtime
и strptime
.
В strptime(fmt)
встроенный разбирает входные строки , соответствующие fmt
аргумент. Выходные данные представлены в виде «разбитого времени», потребляемого gmtime
, а выходного — mktime
.
strftime(fmt)
Встроенная форматирует время (GMT) с заданным форматом. strflocaltime
делает то же самое, но с использованием локальной установки временной зоны.
Строки формата для strptime
и strftime
описаны в типичной документации библиотеки C. Строка формата для даты и времени ISO 8601: "%Y-%m-%dT%H:%M:%SZ"
.
jq может не поддерживать некоторые или все функции этой даты в некоторых системах. В частности, спецификаторы %u
и %j
для strptime(fmt)
не поддерживаются в macOS.
Examples
jq ‘fromdate’ | |
Input | «2015-03-05T23:51:47Z» |
Output | 1425599507 |
jq ‘strptime(«%Y-%m-%dT%H:%M:%SZ»)’ | |
Input | «2015-03-05T23:51:47Z» |
Output | [2015,2,5,23,51,47,4,63] |
jq ‘strptime(«%Y-%m-%dT%H:%M:%SZ»)|mktime’ | |
Input | «2015-03-05T23:51:47Z» |
Output | 1425599507 |
SQL-Style Operators
jq предоставляет несколько операторов в стиле SQL.
- INDEX(stream; index_expression):
Эта встроенная программа создает объект,ключи которого вычисляются по заданному индексному выражению,применяемому к каждому значению из заданного потока.
- JOIN($idx;stream;idx_expr;join_expr):
Этот встроенный модуль объединяет значения из заданного потока в заданный индекс.Ключи индекса вычисляются путем применения данного выражения index к каждому значению из данного потока.Массив из значения в потоке и соответствующего значения из индекса подается на заданное выражение join для получения каждого результата.
- JOIN($idx;stream;idx_expr):
То же, что и JOIN($idx; stream; idx_expr; .)
.
- JOIN($idx; idx_expr):
Эта встроенная функция присоединяется к вводу .
к данному индексу, применяя данное индексное выражение к .
для вычисления индексного ключа. Операция соединения описана выше.
- IN(s):
Эта встроенная функция выводит true
если .
появляется в данном потоке, иначе выводится false
.
- IN(source; s):
Эта встроенная функция выводит true
, если какое-либо значение в исходном потоке появляется во втором потоке, в противном случае выводит false
.
builtins
Возвращает список всех встроенных функций в формате name/arity
. Поскольку функции с тем же именем, но с разной арностью считаются отдельными функциями, all/0
, all/1
и all/2
будут присутствовать в списке.
Условия и сравнения
==
, !=
Выражение ‘a ==b’ выдает ‘true’,если результаты a и b равны (то есть,если они представляют эквивалентные JSON-документы),и ‘false’ в противном случае.В частности,строки никогда не считаются равными числам.Если вы пришли из Javascript,то jq’s ==подобно Javascript’s ===-считает значения равными только тогда,когда они имеют одинаковый тип,а также одинаковое значение.
! = «не равно», а ‘a! = b’ возвращает значение, противоположное ‘a == b’
Example
jq ‘.[]==1’ | |
Input | [1, 1.0, «1», «банан»] |
Output | true |
true | |
false | |
false |
if-then-else
if A then B else C end
будет действовать так же, как B
, если A
производит значение, отличное от false или null, но в противном случае будет действовать так же, как C
.
Проверка на false или null — это более простое понятие «правдивости», чем в Javascript или Python, но это означает, что иногда вам придется более четко указывать желаемое условие: вы не можете проверить, например, строка пусто при использовании if .name then A else B end
, вам понадобится что-то вроде if (.name | length) > 0 then A else B end
вместо этого.
Если условие A
дает несколько результатов, то B
оценивается один раз для каждого результата, который не является ложным или нулевым, а C
оценивается один раз для каждого ложного или нулевого результата.
Если вы используете синтаксис elif A then B
Example
jq ‘if.==0 then «zero» elif.==1 then «one» else «many» end’ | |
Input | 2 |
Output | «many» |
>, >=, <=, <
Операторы сравнения >
, >=
, <=
, <
возвращают, является ли их левый аргумент больше, больше или равен, меньше или равен или меньше их правого аргумента (соответственно).
Порядок совпадает с описанным выше для sort
.
Example
jq ‘. < 5’ | |
Input | 2 |
Output | true |
and/or/not
jq поддерживает обычные булевы операторы and/or/not.Они имеют тот же стандарт истинности,что и выражения if-false и null считаются «ложными значениями»,а все остальное-«истинным значением».
Если операнд одного из этих операторов выдает несколько результатов,то сам оператор будет выдавать результат для каждого входа.
not
на самом деле является встроенной функцией, а не оператором, поэтому он вызывается как фильтр, который может быть передан по конвейеру, а не со специальным синтаксисом, как в .foo and .bar | not
.
Эти три оператора дают только значения «true» и «false»,поэтому они полезны только для настоящих булевых операций,а не для обычной идиомы Perl/Python/Ruby «значение_которое_может_быть_null или по умолчанию».Если вы хотите использовать эту форму «или»,выбирая между двумя значениями,а не оценивая условие,смотрите оператор «//» ниже.
Examples
jq ’42 и «строка»‘ | |
Input | null |
Output | true |
jq ‘(true,false)или false’ | |
Input | null |
Output | true |
false |
jq ‘(true,true)и (true,false)’ | |
Input | null |
Output | true |
false | |
true | |
false |
jq ‘[true,false | not]’ | |
Input | null |
Output | [false, true] |
Альтернативный оператор: //
Фильтр формы a // b
дает те же результаты, что и a
, если a
дает результаты, отличные от false
и null
. В противном случае a // b
дает те же результаты, что и b
.
Это полезно для предоставления значений по умолчанию: .foo // 1
будет оцениваться как 1
, если во входных данных нет элемента .foo
. Это похоже на то, как or
иногда используется в Python ( оператор jq or
зарезервирован для строго логических операций).
Examples
jq ‘.foo //42’ | |
Input | {«foo»: 19} |
Output | 19 |
jq ‘.foo //42’ | |
Input | {} |
Output | 42 |
try-catch
Ошибки можно try EXP catch EXP
с помощью try EXP catch EXP . Выполняется первое выражение, а если оно терпит неудачу, то выполняется второе с сообщением об ошибке. Вывод обработчика, если он есть, выводится так, как если бы это был вывод выражения, которое нужно попробовать.
Форма try EXP
использует в качестве обработчика исключений empty
строку.
Examples
jq ‘try .a catch «.не является объектом»‘ | |
Input | true |
Output | «. не объект» |
jq ‘[.[]|try .a]’ | |
Input | [{}, правда, {«а»: 1}] |
Output | [null, 1] |
jq ‘try error(«какое-то исключение»)catch .’ | |
Input | true |
Output | «some exception» |
Выход из структур контроля
Удобное использование try / catch — выйти из-под контроля таких структур, как reduce
, foreach
, while
и т. Д.
Например:
# Repeat an expression until it raises "break" as an # error, then stop repeating without re-raising the error. # But if the error caught is not "break" then re-raise it. try repeat(exp) catch .=="break" then empty else error;
В jq есть синтаксис для именованных лексических меток «прервать» или «вернуться (назад)к»:
label $out | ... break $out ...
break $label_name
выражение заставит программу действовать так , как будто ближайшая (к левой) label $label_name
производится empty
.
Связь между break
и соответствующей label
является лексической: метка должна быть «видимой» из разрыва.
Чтобы выйти из reduce
, например:
label $out | reduce .[] as $item (null; if .==false then break $out else ... end)
Следующая программа jq выдает синтаксическую ошибку:
break $out
потому что ярлык $out
не виден.
Подавление ошибок / Дополнительный оператор ?
?
оператор, используемый как EXP?
, это сокращение от try EXP
.
Example
jq ‘[.[]|(.a)?]’ | |
Input | [{}, правда, {«а»: 1}] |
Output | [null, 1] |
Регулярные выражения (PCRE)
jq использует библиотеку регулярных выражений Oniguruma,как и php,ruby,TextMate,Sublime Text и т.д.,поэтому описание здесь будет посвящено специфике jq.
Фильтры jq regex определены таким образом,что их можно использовать с помощью одного из этих шаблонов:
STRING | FILTER( REGEX ) STRING | FILTER( REGEX; FLAGS ) STRING | FILTER( [REGEX] ) STRING | FILTER( [REGEX, FLAGS] )
где: STRING, REGEX и FLAGS являются строками jq и подлежат интерполяции строк jq; REGEX после интерполяции строки должен быть допустимым регулярным выражением PCRE; * ФИЛЬТР — это test
, match
или capture
, как описано ниже.
FLAGS-это строка,состоящая из одного или нескольких поддерживаемых флагов:
g
— Глобальный поиск (найти все совпадения, а не только первое)i
— поиск без учета регистраm
— Многострочный режим (‘.’ будет соответствовать символам новой строки)n
— игнорировать пустые совпаденияp
— включены оба режима: s и m.s
— Однострочный режим (‘^’ -> ‘ A’, ‘$’ -> ‘ Z’)l
— найти максимально длинные совпаденияx
— расширенный формат регулярного выражения (игнорировать пробелы и комментарии)
Для сопоставления пробелов в шаблоне x используйте экранирование,такое как s,например.
- test(«asb»,»x» ).
Обратите внимание,что определенные флаги также могут быть указаны в REGEX,например.
- jq -n ‘(«test»,»TEst»,»teST»,»TEST»)| test(«(?i)te(?-i)st» )»
оценивается как:true,true,false,false.
test(val)
, test(regex; flags)
Подобно match
, но не возвращает объекты соответствия, только true
или false
для того, совпадает ли регулярное выражение с вводом.
Examples
jq ‘test(«foo»)’ | |
Input | «foo» |
Output | true |
jq ‘.[]| test(«a b c#пробелы игнорируются»;»ix»)’ | |
Input | [«xabcd», «ABC»] |
Output | true |
true |
match(val)
, match(regex; flags)
match выводит объект для каждого найденного совпадения. В матчах есть следующие поля:
offset
— смещение в кодовых точках UTF-8 от начала вводаlength
— длина совпадения в кодовых точках UTF-8string
— строка, которая соответствуетcaptures
— массив объектов, представляющих группы захвата.
Объекты группы захвата имеют следующие поля:
offset
— смещение в кодовых точках UTF-8 от начала вводаlength
— длина в кодовых точках UTF-8 этой группы захватаstring
— строка, которая была захваченаname
— имя группы захвата (илиnull
, если она была безымянной)
Захват групп,которые ни с чем не совпали,возвращает смещение -1
Examples
jq ‘match(«(abc)+»;»g»)’ | |
Input | «abc abc» |
Output | {«смещение»: 0, «длина»: 3, «строка»: «abc», «захватов»: [{«смещение»: 0, «длина»: 3, «строка»: «abc», «имя» : ноль}]} |
{«смещение»: 4, «длина»: 3, «строка»: «abc», «захват»: [{«смещение»: 4, «длина»: 3, «строка»: «abc», «имя» : ноль}]} |
jq ‘match(«foo»)’ | |
Input | «фу бар фу» |
Output | {«смещение»: 0, «длина»: 3, «строка»: «foo», «захватов»: []} |
jq ‘match([«foo»,»ig»])’ | |
Input | «foo bar FOO» |
Output | {«смещение»: 0, «длина»: 3, «строка»: «foo», «захватов»: []} |
{«смещение»: 8, «длина»: 3, «строка»: «FOO», «захватов»: []} |
jq ‘match(«foo (?<bar123>bar)? foo»; «ig»)’ | |
Input | «фу бар фу фу фу» |
Output | {«offset»: 0, «length»: 11, «string»: «foo bar foo», «captures»: [{«offset»: 4, «length»: 3, «string»: «bar», «name»: «bar123»}]} |
{«смещение»: 12, «длина»: 8, «строка»: «foo foo», «захватов»: [{«смещение»: -1, «длина»: 0, «строка»: null, «имя» : «bar123»}]} |
jq ‘[match(«.»;»g»)]| length’ | |
Input | «abc» |
Output | 3 |
capture(val)
, capture(regex; flags)
Собирает именованные захваты в объект JSON,где имя каждого захвата является ключом,а совпадающая строка-соответствующим значением.
Example
jq ‘capture(«(?<a>[a-z]+)-(?<n>[0-9]+)»)’ | |
Input | «xyzzy-14» |
Output | { «a»: «xyzzy», «n»: «14» } |
scan(regex)
, scan(regex; flags)
Испускает поток неперекрывающихся подстрок ввода, которые соответствуют регулярному выражению в соответствии с флагами, если таковые были указаны. Если совпадений нет, поток пуст. Чтобы захватить все совпадения для каждой входной строки, используйте идиому [ expr ]
, например [ scan(regex) ]
.
split(regex; flags)
Для обратной совместимости split
разбивается на строку, а не на регулярное выражение.
splits(regex)
, splits(regex; flags)
Они обеспечивают те же результаты, что и их split
аналоги, но в виде потока, а не массива.
sub(regex; tostring)
sub(regex; string; flags)
Выпустить строку, полученную заменой первого совпадения регулярного выражения во входной строке на tostring
после интерполяции. tostring
должен быть строкой jq и может содержать ссылки на именованные записи. Именованные захваты, по сути, представляются в виде объекта JSON (созданного с помощью capture
) для tostring
, поэтому ссылка на захваченную переменную с именем «x» будет иметь форму: «(.x)».
gsub(regex; string)
, gsub(regex; string; flags)
gsub
похож на sub
, но все неперекрывающиеся вхождения регулярного выражения заменяются строкой после интерполяции.
Advanced features
Переменные являются абсолютной необходимостью в большинстве языков программирования,но в jq они отнесены к «расширенным возможностям».
В большинстве языков переменные являются единственным средством передачи данных.Если вы вычисляете значение и хотите использовать его более одного раза,вам нужно сохранить его в переменной.Чтобы передать значение в другую часть программы,вам нужно,чтобы эта часть программы определила переменную (как параметр функции,член объекта или что-то еще),в которую можно поместить данные.
Также возможно определять функции в jq, хотя это функция, наибольшее применение которой — определение стандартной библиотеки jq (многие функции jq, такие как map
и find
, фактически написаны на jq).
В jq есть операторы редукции,которые очень мощные,но немного хитрые.Опять же,они в основном используются внутри,для определения некоторых полезных частей стандартной библиотеки jq.
Это может быть неочевидно сначала,но jq-это генераторы (да,как часто встречается в других языках).Для работы с генераторами предусмотрены некоторые утилиты.
Имеется минимальная поддержка ввода-вывода (кроме чтения JSON со стандартного ввода и записи JSON на стандартный вывод).
Наконец,существует система модулей/библиотек.
Оператор привязки переменных / символов: ... as $identifier | ...
В jq все фильтры имеют вход и выход, поэтому нет необходимости вручную передавать значение из одной части программы в другую. Многие выражения, например a + b
, передают свой ввод двум различным подвыражениям (здесь a
и b
передаются один и тот же ввод), поэтому переменные обычно не нужны, чтобы использовать значение дважды.
Например, для вычисления среднего значения массива чисел в большинстве языков требуется несколько переменных — по крайней мере, одна для хранения массива, возможно, одна для каждого элемента или для счетчика цикла. В jq это просто add / length
— выражение add
получает массив и производит его сумму, а выражение length
дает массив и производит его длину.
Итак, обычно существует более чистый способ решить большинство проблем в jq, чем определение переменных. Тем не менее, иногда они действительно упрощают задачу, поэтому jq позволяет вам определять переменные, используя expression as $variable
. Все имена переменных начинаются с $
. Вот несколько уродливая версия примера усреднения массива:
length as $array_length | add / $array_length
Нам понадобится более сложная задача,чтобы найти ситуацию,когда использование переменных действительно облегчает нам жизнь.
Предположим,у нас есть массив записей блога с полями «автор» и «заголовок»,а также еще один объект,который используется для сопоставления имен пользователей авторов с реальными именами.Наши входные данные выглядят следующим образом:
{"posts": [{"title": "Frist psot", "author": "anon"}, {"title": "A well-written article", "author": "person1"}], "realnames": {"anon": "Anonymous Coward", "person1": "Person McPherson"}}
Мы хотим создавать посты с полем «Автор»,содержащим реальное имя,как в примере:
{"title": "Frist psot", "author": "Anonymous Coward"} {"title": "A well-written article", "author": "Person McPherson"}
Мы используем переменную $names для хранения объекта realnames,чтобы впоследствии ссылаться на него при поиске имен авторов:
.realnames as $names | .posts[] | {title, author: $names[.author]}
Выражение exp as $x | ...
означает: для каждого значения выражения exp
запустить оставшуюся часть конвейера со всем исходным вводом и с $x
установленным на это значение. Таким образом, as
функционирует как нечто вроде цикла foreach.
Как {foo}
— удобный способ записи {foo: .foo}
, так и {$foo}
— удобный способ записи {foo:$foo}
.
Несколько переменных могут быть объявлены с использованием одного выражения as
путем предоставления шаблона, который соответствует структуре ввода (это известно как «деструктуризация»):
. as {realnames: $names, posts: [$first, $second]} | ...
Объявления переменных в шаблонах массива (например,. As . as [$first, $second]
) привязываются к элементам массива от элемента с нулевым индексом вверх по порядку. Когда нет значения в индексе для элемента шаблона массива, к этой переменной привязывается значение null
.
Переменные масштабируются по остальной части выражения,которое их определяет,поэтому
.realnames as $names | (.posts[] | {title, author: $names[.author]})
будет работать,но
(.realnames as $names | .posts[]) | {title, author: $names[.author]}
won’t.
Для теоретиков языка программирования более точным будет сказать,что переменные jq-это лексически скопированные привязки.В частности,нет способа изменить значение привязки;можно только установить новую привязку с тем же именем,но которая не будет видна на месте старой.
Examples
jq ‘.bar as $x | .foo |.+$x’ | |
Input | {«foo»:10, «bar»:200} |
Output | 210 |
jq ‘.as $i|[(.*2|.as $i| $i),$i]’ | |
Input | 5 |
Output | [10,5] |
jq ‘.as [$a,$b,{c:$c}]| $a+$b+$c’ | |
Input | [2, 3, {«c»: 4, «d»: 5}] |
Output | 9 |
jq ‘.[]as [$a,$b]| {a:$a,b:$b}’ | |
Input | [[0], [0, 1], [2, 1, 0]] |
Output | {«a»:0,»b»:null} |
{«a»:0,»b»:1} | |
{«a»:2,»b»:1} |
Деструктуризация альтернативного оператора ?//
Альтернативный оператор деструктуризации предоставляет лаконичный механизм для деструктуризации входных данных,которые могут принимать одну из нескольких форм.
Предположим,у нас есть API,который возвращает список ресурсов и связанных с ними событий,и мы хотим получить идентификатор пользователя и временную метку первого события для каждого ресурса.API (неуклюже преобразованный из XML)обернет события в массив,только если ресурс имеет несколько событий:
{"resources": [{"id": 1, "kind": "widget", "events": {"action": "create", "user_id": 1, "ts": 13}}, {"id": 2, "kind": "widget", "events": [{"action": "create", "user_id": 1, "ts": 14}, {"action": "destroy", "user_id": 1, "ts": 15}]}]}
Мы можем использовать альтернативный оператор деструктуризации для простой обработки этого структурного изменения:
.resources[] as {$id, $kind, events: {$user_id, $ts}} ?// {$id, $kind, events: [{$user_id, $ts}]} | {$user_id, $kind, $id, $ts}
Или,если мы не уверены,что входные данные-это массив значений или объект:
.[] as [$id, $kind, $user_id, $ts] ?// {$id, $kind, $user_id, $ts} | ...
В каждой альтернативе нет необходимости определять все те же переменные, но все названные переменные будут доступны для последующего выражения. Переменные, не найденные в альтернативном варианте, будут иметь значение null
:
.resources[] as {$id, $kind, events: {$user_id, $ts}} ?// {$id, $kind, events: [{$first_user_id, $first_ts}]} | {$user_id, $first_user_id, $kind, $id, $ts, $first_ts}
Кроме того,если последующее выражение возвращает ошибку,альтернативный оператор попытается попробовать следующее связывание.Ошибки,возникающие во время последней альтернативы,передаются дальше.
[[3]] | .[] as [$a] ?// [$b] | if $a != null then error("err: ($a)") else {$a,$b} end
Examples
jq ‘.[]as {$a,$b,c:{$d,$e}}?//{$a,$b,c:[{$d,$e}]}| {$a,$b,$d,$e}}». | |
Input | [{«a»: 1, «b»: 2, «c»: {«d»: 3, «e»: 4}}, {«a»: 1, «b»: 2, «c»: [{«d»: 3, «e»: 4}]}] |
Output | {«a»:1,»b»:2,»d»:3,»e»:4} |
{«a»:1,»b»:2,»d»:3,»e»:4} |
jq ‘.[]as {$a,$b,c:{$d}}?//{$a,$b,c:[{$e}]}| {$a,$b,$d,$e}}». | |
Input | [{«a»: 1, «b»: 2, «c»: {«d»: 3, «e»: 4}}, {«a»: 1, «b»: 2, «c»: [{«d»: 3, «e»: 4}]}] |
Output | {«a»:1,»b»:2,»d»:3,»e»:null} |
{«a»:1,»b»:2,»d»:null,»e»:4} |
jq ‘.[]as [$a]?//[$b]| if $a !=null then error(«err:($a)»)else {$a,$b}end’ | |
Input | [[3]] |
Output | {«a»:null,»b»:3} |
Определение функций
Вы можете дать фильтру имя,используя синтаксис «def»:
def increment: . + 1;
С этого момента increment
можно использовать в качестве фильтра, как и встроенную функцию (фактически, именно столько встроенных функций определено). Функция может принимать аргументы:
def map(f): [.[] | f];
Аргументы передаются как фильтры (функции без аргументов), а не как значения. На один и тот же аргумент можно ссылаться несколько раз с разными входными данными (здесь f
запускается для каждого элемента входного массива). Аргументы функции больше похожи на обратные вызовы, чем на аргументы значения. Это важно понимать. Рассмотреть возможность:
def foo(f): f|f; 5|foo(.*2)
Результатом будет 20, потому что f
равно .*2
и во время первого вызова f
.
будет 5, а во второй раз будет 10 (5 * 2), поэтому результат будет 20. Аргументы функции — это фильтры, а фильтры ожидают ввода при вызове.
Если вам нужно поведение «значение-аргумент» для определения простых функций,вы можете просто использовать переменную:
def addvalue(f): f as $f | map(. + $f);
Или воспользуйтесь сокращением:
def addvalue($f): ...;
При любом определении addvalue(.foo)
добавит поле .foo
текущего ввода к каждому элементу массива. Обратите внимание, что вызов addvalue(.[])
тому, что часть map(. + $f)
будет оцениваться один раз для каждого значения в значении .
на месте звонка.
Допускается несколько определений,использующих одно и то же имя функции.Каждое переопределение заменяет предыдущее для того же количества аргументов функции,но только для ссылок из функций (или основной программы),следующих за переопределением.См.также раздел ниже о масштабировании.
Examples
jq ‘def addvalue(f):.+[f];map(addvalue(.[0]))’ | |
Input | [[1,2],[10,20]] |
Output | [[1,2,1], [10,20,10]] |
jq ‘def addvalue(f):f as $x | map(.+$x);addvalue(.[0])’ | |
Input | [[1,2],[10,20]] |
Output | [[1,2,1,2], [10,20,1,2]] |
Scoping
В jq есть два типа символов:привязки значений (они же «переменные»)и функции.И те,и другие имеют лексическую привязку,причем выражения могут ссылаться только на символы,которые были определены «слева» от них.Единственным исключением из этого правила является то,что функции могут ссылаться на самих себя,чтобы иметь возможность создавать рекурсивные функции.
Например, в следующем выражении есть привязка, которая видна «справа» от нее, ... | .*3 as $times_three | [. + $times_three] | ...
, а не «налево». Теперь рассмотрим это выражение ... | (.*3 as $times_three | [.+ $times_three]) | ...
: здесь связывание $times_three
это не виден мимо закрывающая скобка.
Reduce
reduce
синтаксис в JQ позволяет объединить все результаты выражения, накапливая их в один ответ. В качестве примера мы передадим [3,2,1]
этому выражению:
reduce .[] as $item (0; . + $item)
Для каждого результата , что .[]
Производит . + $item
запускается для накопления промежуточной суммы, начиная с 0. В этом примере .[]
дает результаты 3, 2 и 1, поэтому эффект аналогичен запуску чего-то вроде этого:
0 | (3 as $item | . + $item) | (2 as $item | . + $item) | (1 as $item | . + $item)
Example
jq ‘reduce .[]as $item (0;.+$item)’ | |
Input | [10,2,5,3] |
Output | 20 |
isempty(exp)
Возвращает true, если exp
не производит выходных данных, иначе false.
Example
jq ‘isempty(empty)’ | |
Input | null |
Output | true |
limit(n; exp)
Функция limit
извлекает до n
выходов из exp
.
Example
jq ‘[limit(3;.[])]’ | |
Input | [0,1,2,3,4,5,6,7,8,9] |
Output | [0,1,2] |
first(expr)
, last(expr)
, nth(n; expr)
Функции first(expr)
и last(expr)
извлекают первое и последнее значения из expr
соответственно.
Функция nth(n; expr)
извлекает n-е значение, выводимое expr
. Это можно определить как def nth(n; expr): last(limit(n + 1; expr));
. Обратите внимание, что nth(n; expr)
не поддерживает отрицательные значения n
.
Example
jq ‘[first(range(.)),last(range(.)),nth(./2;range(.))]’ | |
Input | 10 |
Output | [0,9,5] |
first
, last
, nth(n)
В first
и last
функции извлечения первого и последнего значения из любого массива в .
.
Функция nth(n)
извлекает n-е значение любого массива в .
.
Example
jq ‘[range(.)]|[first,last,nth(5)]’ | |
Input | 10 |
Output | [0,9,5] |
foreach
foreach
синтаксис аналогичен reduce
, но предназначен , чтобы позволить строительство limit
и восстановителей , которые производят промежуточные результаты (смотрите пример).
Форма — foreach EXP as $var (INIT; UPDATE; EXTRACT)
. Как и reduce
, INIT
оценивается один раз для получения значения состояния, затем каждый вывод EXP
привязан к $var
, UPDATE
оценивается для каждого вывода EXP
с текущим состоянием и с видимым $var
. Каждое значение, выводимое с помощью UPDATE
, заменяет предыдущее состояние. Наконец, EXTRACT
оценивается для каждого нового состояния, чтобы извлечь вывод foreach
.
Это в основном полезно только для построения функций, подобных reduce
и limit
. Но он гораздо более общий, поскольку позволяет частичное сокращение (см. Пример ниже).
Example
jq ‘[foreach .[]as $item ([[],[]];if $item ==null then [[],.[0]]else [(.[0]+[$item]),[]]end;if $item ==null then .[1]else empty end)]]». | |
Input | [1,2,3,4,null,»a»,»b»,null] |
Output | [[1,2,3,4],[«a»,»b»]] |
Recursion
Как описано выше, recurse
использования рекурсия, и любая функция JQ может быть рекурсивной. while
встроенная команда также реализуется в терминах рекурсии.
Хвостовые вызовы оптимизируются всякий раз,когда выражение слева от рекурсивного вызова выводит свое последнее значение.На практике это означает,что выражение слева от рекурсивного вызова не должно выдавать более одного выхода на каждый вход.
Например:
def recurse(f): def r: ., (f | select(. != null) | r); r; def while(cond; update): def _while: if cond then ., (update | _while) else empty end; _while; def repeat(exp): def _repeat: exp, _repeat; _repeat;
Генераторы и итераторы
Некоторые операторы и функции jq на самом деле являются генераторами в том смысле, что они могут выдавать ноль, одно или несколько значений для каждого ввода, как и следовало ожидать от других языков программирования, имеющих генераторы. Например,. .[]
Генерирует все значения во входных данных (которые должны быть массивом или объектом), range(0; 10)
генерирует целые числа от 0 до 10 и так далее.
Даже оператор запятой является генератором,генерируя сначала значения,порожденные выражением слева от запятой,а затем для каждого из них значения,порожденные выражением справа от запятой.
empty
встроенный является генератором , который производит нулевые выходы. В empty
BUILTIN откатывается к выражению предшествующего генератора.
Все функции jq могут быть генераторами, просто используя встроенные генераторы. Также возможно определить новые генераторы, используя только рекурсию и оператор запятой. Если рекурсивный вызов (ы) находится (находятся) «в хвостовой позиции», то генератор будет эффективным. В приведенном ниже примере рекурсивный вызов _range
самому себе находится в хвостовой позиции. В этом примере показаны три дополнительные темы: хвостовая рекурсия, построение генератора и подфункции.
Examples
jq ‘def range (init; upto; by): def _range: if (by> 0 и. <upto) или (by <0 and.> upto) then., ((. + by) | _range) else. конец; если по == 0, то init else init | _range end | выберите ((по> 0 и. <до) или (по <0 и.> до)); диапазон (0; 10; 3) ‘ | |
Input | null |
Output | 0 |
3 | |
6 | |
9 |
jq ‘def while (cond; update): def _ while: if cond then., (update | _ while) else empty end; _пока; [в то время как (. <100;. * 2)] ‘ | |
Input | 1 |
Output | [1,2,4,8,16,32,64] |
Math
В настоящее время jq поддерживает только числа двойной точности IEEE754 (64-битные)с плавающей запятой.
Помимо простых арифметических операторов, таких как +
, jq также имеет большинство стандартных математических функций из математической библиотеки C. Математические функции C, которые принимают единственный входной аргумент (например, sin()
), доступны как jq-функции с нулевым аргументом. Математические функции C, которые принимают два входных аргумента (например, pow()
), доступны как функции jq с двумя аргументами, которые игнорируют .
. Математические функции C, которые принимают три входных аргумента, доступны как функции jq с тремя аргументами, которые игнорируют .
.
Доступность стандартных математических функций зависит от наличия соответствующих математических функций в вашей операционной системе и математической библиотеке C.Недоступные математические функции будут определены,но вызовут ошибку.
Один вход C математические функции: acos
acosh
asin
asinh
atan
atanh
cbrt
ceil
cos
cosh
erf
erfc
exp
exp10
exp2
expm1
fabs
floor
gamma
j0
j1
lgamma
log
log10
log1p
log2
logb
nearbyint
pow10
rint
round
significand
sin
sinh
sqrt
tan
tanh
tgamma
trunc
y0
y1
.
Два входных С математические функции: atan2
copysign
drem
fdim
fmax
fmin
fmod
frexp
hypot
jn
ldexp
modf
nextafter
nexttoward
pow
remainder
scalb
scalbln
yn
.
Математические функции C с тремя входами: fma
.
Более подробную информацию о каждом из них см.в руководстве к вашей системе.
I/O
В настоящее время jq имеет минимальную поддержку ввода-вывода, в основном в форме контроля над чтением входных данных. Две встроенные функции функции предусмотрены для этого, input
и inputs
, которые считывают из одних и тех же источников (например, stdin
, файлы , названные в командной строке) , как самого JQ. Эти две встроенные команды и собственные действия чтения jq могут чередоваться друг с другом.
Две встроенные команды обеспечивают минимальные возможности вывода, debug
и stderr
. (Напомним, что выходные значения программы jq всегда выводятся в виде текстов JSON на стандартный stdout
.) Встроенная функция debug
может иметь поведение, зависящее от приложения, например, для исполняемых файлов, которые используют libjq C API, но не являются самим исполняемым файлом jq. stderr
встроенный выводит входные данные в нестандартном режиме для stder без дополнительной отделки, даже не новой строки.
Большинство встроенных модулей jq являются ссылочно прозрачными и дают постоянные и повторяющиеся потоки значений при применении к постоянным входам.Это не относится к встроенным модулям ввода/вывода.
input
Выводит один новый вход.
inputs
Выводит все оставшиеся входы один за другим.
Это в первую очередь полезно для сокращений над входами программы.
debug
Вызывает сообщение отладки на основе входного значения. Исполняемый файл jq обертывает входное значение с помощью ["DEBUG:", <input-value>]
и компактно печатает это и новую строку на stderr. Это может измениться в будущем.
stderr
Выводит входные данные в необработанном и компактном виде на stderr без каких-либо дополнительных украшений,даже без новой строки.
input_filename
Возвращает имя файла,входные данные которого в данный момент фильтруются.Обратите внимание,что это не будет работать хорошо,если jq не работает в локали UTF-8.
input_line_number
Возвращает номер строки ввода,который в данный момент фильтруется.
Streaming
С --stream
вариантом JQ может разобрать ввод текст в потоковом режиме, позволяя программу JQ , чтобы начать обработку больших текстов в формате JSON , а не сразу после разбора её создания . Если у вас есть один текст JSON размером 1 ГБ, его потоковая передача позволит вам обработать его гораздо быстрее.
Однако с потоковой передачей справиться непросто, поскольку программа jq будет иметь в качестве входных данных [<path>, <leaf-value>]
(и несколько других форм).
Для облегчения работы с потоками предусмотрено несколько встроенных модулей.
В приведенных ниже примерах используется потоковая форма [0,[1]]
, то есть [[0],0],[[1,0],1],[[1,0]],[[1]]
» .
Формы потоковой передачи включают [<path>, <leaf-value>]
(для обозначения любого скалярного значения, пустого массива или пустого объекта) и [<path>]
(для обозначения конца массива или объекта). Будущие версии jq, запускаемые с --stream
и -seq
, могут выводить дополнительные формы, такие как ["error message"]
когда входной текст не удается проанализировать.
truncate_stream(stream_expression)
Принимает на вход число и усекает соответствующее количество элементов пути слева от выходов заданного потокового выражения.
Example
jq ‘[1|truncate_stream([[0],1],[[1,0],2],[[1,0]],[[1]])]’ | |
Input | 1 |
Output | [[[0],2],[[0]]] |
fromstream(stream_expression)
Выводит значения,соответствующие выходам потокового выражения.
Example
jq ‘fromstream(1|truncate_stream([[0],1],[[1,0],2],[[1,0]],[[1]]))’ | |
Input | null |
Output | [2] |
tostream
tostream
встроенных выходов поточной формы его ввода.
Example
jq ‘.as $dot|fromstream($dot|tostream)|.==$dot’ | |
Input | [0,[1,{«a»:1},{«b»:2}]] |
Output | true |
Assignment
В jq присваивание работает немного иначе,чем в большинстве языков программирования.jq не делает различий между ссылками и копиями чего-либо-два объекта или массива либо равны,либо не равны,без дальнейшего понятия «один и тот же объект» или «не один и тот же объект».
Если у объекта есть два поля, которые являются массивами, .foo
и .bar
, и вы добавляете что-то в .foo
, то .bar
не станет больше, даже если вы ранее установили .bar = .foo
. Если вы привыкли программировать на таких языках, как Python, Java, Ruby, Javascript и т. Д., Тогда вы можете думать об этом так, как будто jq делает полную глубокую копию каждого объекта, прежде чем он выполнит назначение (для производительности он на самом деле не сделайте это, но это общая идея).
Это означает,что в jq невозможно построить циклические значения (например,массив,первым элементом которого является он сам).Это сделано намеренно и гарантирует,что все,что может создать программа jq,может быть представлено в JSON.
Все операторы присваивания в jq имеют выражения пути в левой части (LHS).Правая часть (RHS)предоставляет значения для установки на пути,названные выражениями путей LHS.
Значения в jq всегда неизменны. Внутренне присваивание работает с использованием сокращения для вычисления новых значений замены .
к которым были применены все желаемые задания .
, а затем вывод измененного значения. Это можно пояснить на следующем примере: {a:{b:{c:1}}} | (.a.b|=3), .
. Это будет выводить {"a":{"b":3}}
и {"a":{"b":{"c":1}}}
, так как последнее подвыражением, .
, видит исходное значение, а не измененное значение.
Большинство пользователей захотят использовать операторы присваивания модификации, такие как |=
или +=
, а не =
.
Обратите внимание, что LHS операторов присваивания относится к значению в .
. Таким образом, $var.foo = 1
не будет работать $var.foo
( $ var.foo не является допустимым или полезным выражением пути в .
); использовать $var | .foo = 1
вместо этого.
Обратите внимание также , что .a,.b=0
не множество .a
и .b
, но (.a,.b)=0
устанавливает оба.
Update-assignment: |=
Это оператор «обновления» ‘| =’. Он берет фильтр с правой стороны и определяет новое значение для свойства .
присваивается, пропуская через это выражение старое значение. Например, (.foo, .bar) | =. + 1 будет строить объект с полем «foo», установленным на «foo» плюс 1, а в поле «bar» — «bar» ввода плюс 1. .
Левая часть может быть любым общим выражением пути; см. path()
.
Обратите внимание, что левая часть ‘| =’ относится к значению в .
. Таким образом, $var.foo |= . + 1
не будет работать $var.foo
( $ var.foo не является допустимым или полезным выражением пути в .
); использовать $var | .foo |= . + 1
вместо этого.
Если правая часть не выводит никаких значений (т. empty
), то левосторонний путь будет удален, как и с del(path)
.
Если правая часть выводит несколько значений,будет использоваться только первое из них (ПРИМЕЧАНИЕ ПО СОВМЕСТИМОСТИ:в jq 1.5 и более ранних версиях раньше использовалось только последнее значение).
Example
jq ‘(..|select(type==»boolean»))|=if.then 1 else 0 end’ | |
Input | [true,false,[5,true,[true,[false]],false]] |
Output | [1,0,[5,1,[1,[0]],0]] |
Арифметическое обновление-присвоение: +=
, -=
, *=
, /=
, %=
, //=
jq имеет несколько операторов вида a op= b
, которые все эквивалентны a |= . op b
. Таким образом, для увеличения значений можно использовать += 1
, который совпадает с |= . + 1
.
Example
jq ‘.foo +=1’ | |
Input | {«foo»: 42} |
Output | {«foo»: 43} |
Простое присвоение: =
Это обычный оператор присваивания.В отличие от других,на вход правой части (RHS)подается то же значение,что и на вход левой части (LHS),а не значение на пути LHS,и все значения,выводимые RHS,будут использоваться (как показано ниже).
Если правая часть ‘=’ дает несколько значений, то для каждого такого значения jq установит пути в левой части к значению, а затем выведет измененное значение .
. Например, (.a,.b)=range(2)
выводит {"a":0,"b":0}
, затем {"a":1,"b":1}
. Формы присвоения «обновления» (см. Выше) этого не делают.
Этот пример должен показать разницу между ‘=’ и ‘|=’:
Обеспечьте ввод ‘{«a»:{«b»:10},»b»:20}’ программам:
.a = .b
.a |= .b
Первый установит поле «a» входа в поле «b» входа и выдаст выход {«a»:20,»b»:20}.Во втором случае поле «a» входа будет установлено в поле «b» поля «a»,в результате чего будет получено {«a»:10,»b»:20}.
Еще один пример разницы между ‘=’ и ‘|=’:
null|(.a,.b)=range(3)
выводит ‘{«a»:0,»b»:0}’,'{«a»:1,»b»:1}’ и ‘{«a»:2,»b»:2}’,в то время как
null|(.a,.b)|=range(3)
выводит только ‘{«a»:0,»b»:0}’.
Комплексные задания
В левой части jq-задания разрешено гораздо больше вещей,чем в большинстве языков.Мы уже видели простые доступы к полям в левой части,и неудивительно,что доступ к массивам работает так же хорошо:
.posts[0].title = "JQ Manual"
Неожиданностью может стать то,что выражение слева может давать несколько результатов,относящихся к разным точкам входного документа:
.posts[].comments |= . + ["this is great"]
Этот пример добавляет строку «this is great» в массив «comments» каждого сообщения во входных данных (где входные данные-это объект с полем «posts»,которое представляет собой массив сообщений).
Когда jq встречает задание типа ‘a=b’,он записывает «путь»,пройденный для выбора части входного документа при выполнении a.Этот путь затем используется для поиска того,какую часть входного документа нужно изменить при выполнении задания.В левой части равенства можно использовать любой фильтр-какой бы путь он ни выбрал из входного документа,именно там будет выполняться присваивание.
Это очень мощная операция.Предположим,что мы хотим добавить комментарий к записям в блоге,используя тот же вход «blog»,что и выше.На этот раз мы хотим прокомментировать только посты,написанные «stedolan».Мы можем найти эти записи с помощью функции «select»,описанной ранее:
.posts[] | select(.author == "stedolan")
Пути,предоставляемые этой операцией,указывают на каждое из сообщений,которые написал «stedolan»,и мы можем комментировать каждое из них так же,как и раньше:
(.posts[] | select(.author == "stedolan") | .comments) |= . + ["terrible."]
Modules
jq имеет систему библиотек / модулей. Модули — это файлы, имена которых заканчиваются на .jq
.
Модули, импортированные программой, ищутся по пути поиска по умолчанию (см. Ниже). import
и include
директивы позволяют импортеру изменить этот путь.
Пути в пути поиска подвергаются различным заменам.
Для путей,начинающихся с «~/»,домашний каталог пользователя заменяется на «~».
Для путей,начинающихся с «$ORIGIN/»,путь исполняемого файла jq заменяется на «$ORIGIN».
Для путей,начинающихся с «./»,или путей,содержащих «.»,вместо «.» подставляется путь включающего файла.Для программ верхнего уровня,заданных из командной строки,используется текущий каталог.
Директивы импорта могут опционально указывать путь поиска,к которому добавляется путь по умолчанию.
Путь поиска по умолчанию — это путь поиска, указанный в параметре командной строки -L
, else ["~/.jq", "$ORIGIN/../lib/jq", "$ORIGIN/../lib"]
.
Нулевые и пустые строковые элементы пути завершают обработку пути поиска.
Зависимость с относительным путем «foo/bar» будет искаться в «foo/bar.jq» и «foo/bar/bar.jq» в заданном пути поиска.Это сделано для того,чтобы модули можно было помещать в каталог вместе,например,с файлами контроля версий,файлами README и т.д.,а также для того,чтобы можно было использовать однофайловые модули.
Последовательные компоненты с одинаковым именем не допускаются,чтобы избежать двусмысленности (например,»foo/foo»).
Например, -L$HOME/.jq
модуль foo
можно найти в $HOME/.jq/foo.jq
и $HOME/.jq/foo/foo.jq
.
Если «$HOME/.jq»-это файл,то он передается в основную программу.
import RelativePathString as NAME [<metadata>];
Импортирует модуль,найденный по заданному пути относительно каталога в пути поиска.К строке относительного пути будет добавлен суффикс «.jq».Символы модуля имеют префикс «NAME::».
Необязательные метаданные должны быть постоянным выражением jq. Это должен быть объект с такими ключами, как «домашняя страница» и так далее. В настоящее время jq использует только «поисковый» ключ / значение метаданных. Метаданные также доступны пользователям через встроенный modulemeta
.
Ключ «search» в метаданных,если он присутствует,должен иметь строковое значение или значение массива (массив строк);это путь поиска,который должен быть префиксом к пути поиска верхнего уровня.
include RelativePathString [<metadata>];
Импортирует модуль,найденный по заданному пути относительно каталога в пути поиска,как если бы он был включен на место.К строке относительного пути будет добавлен суффикс «.jq».Символы модуля импортируются в пространство имен вызывающей стороны,как если бы содержимое модуля было включено напрямую.
Необязательные метаданные должны быть постоянным выражением jq. Это должен быть объект с такими ключами, как «домашняя страница» и так далее. В настоящее время jq использует только «поисковый» ключ / значение метаданных. Метаданные также доступны пользователям через встроенный modulemeta
.
import RelativePathString as $NAME [<metadata>];
Импортирует файл JSON, найденный по заданному пути, относительно каталога в пути поиска. К строке относительного пути будет добавлен суффикс «.json». Данные файла будут доступны как $NAME::NAME
.
Необязательные метаданные должны быть постоянным выражением jq. Это должен быть объект с такими ключами, как «домашняя страница» и так далее. В настоящее время jq использует только «поисковый» ключ / значение метаданных. Метаданные также доступны пользователям через встроенный modulemeta
.
Ключ «search» в метаданных,если он присутствует,должен иметь строковое значение или значение массива (массив строк);это путь поиска,который должен быть префиксом к пути поиска верхнего уровня.
module <metadata>;
Эта директива не обязательна. Это не требуется для правильной работы. Он служит только для предоставления метаданных, которые можно прочитать с modulemeta
встроенного модуля modulemeta .
Метаданные должны быть постоянным выражением jq. Это должен быть объект с ключами типа «домашняя страница». В настоящее время jq не использует эти метаданные, но они доступны пользователям через встроенный modulemeta
.
modulemeta
Принимает имя модуля в качестве входных данных и выводит метаданные модуля в виде объекта,с импортом модуля (включая метаданные)в качестве значения массива для ключа «deps».
Программы могут использовать его для запроса метаданных модуля,которые затем можно использовать,например,для поиска,загрузки и установки недостающих зависимостей.
Colors
Чтобы настроить альтернативные цвета, просто установите JQ_COLORS
среды JQ_COLORS в разделенный двоеточиями список частичных управляющих последовательностей терминала, таких как "1;31"
, в следующем порядке:
- цвет для
null
- цвет для
false
- цвет для
true
- цвет для цифр
- цвет для струн
- цвет для массивов
- цвет для объектов
Цветовая схема по умолчанию такая же, как и для параметра "JQ_COLORS=1;30:0;37:0;37:0;37:0;32:1;37:1;37"
.
Это не руководство для эскейпов VT100/ANSI.Однако каждая из этих цветовых спецификаций должна состоять из двух чисел,разделенных точкой с запятой,где первое число-одно из этих:
- 1 (bright)
- 2 (dim)
- 4 (underscore)
- 5 (blink)
- 7 (reverse)
- 8 (hidden)
а второй-один из этих:
- 30 (black)
- 31 (red)
- 32 (green)
- 33 (yellow)
- 34 (blue)
- 35 (magenta)
- 36 (cyan)
- 37 (white)
© 2012 Стивен Долан