Архив метки: Утилиты командной строки

Полезные команды Linux. Манипуляции с текстом

Вывести содержимое файла, нумеруя выводимые строки




cat -n file1




Вывести только не четные строки файла




cat example.txt | awk 'NR%2==1'




Вывести первую и третью колонки. Разделение, по-умолчанию, по пробельным символам или символу табуляции




echo a b c | awk '{print $1,$3}'




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




echo a b c | awk '{print $1}'




Сравнить содержимое двух файлов, удаляя строки встречающиеся в обоих файлах




comm -3 file1 file2




Сравнить содержимое двух файлов, не отображая строки принадлежащие файлу file1




comm -1 file1 file2




Сравнить содержимое двух файлов, не отображая строки принадлежащие файлу file2




comm -2 file1 file2




Отобрать и вывести строки содержащие цифровые символы из файла /var/log/messages




grep [0-9] /var/log/messages




Отобрать и вывести строки, начинающиеся с сочетания символов «Aug», из файла /var/log/messages




grep ^Aug /var/log/messages




Отобрать и вывести строки, содержащие сочетание символов «Aug» из файла /var/log/messages




grep Aug /var/log/messages




Отобрать и вывести строки, содержащие сочетание символов «Aug», из всех файлов, расположенных в директории /var/log и ниже




grep Aug -R /var/log/*




Объединить содержимое file1 и file2 в виде таблицы с разделителем «+»




paste -d '+' file1 file2




Объединить содержимое file1 и file2 в виде таблицы: строка 1 из file1 = строка 1 колонка 1-n, строка 1 из file2 = строка 1 колонка n+1-m




paste file1 file2




Сравнить содержимое двух файлов




sdiff file1 file2




Заменить string1 на string2 в файле example.txt и вывести содержимое




sed 's/string1/string2/g' example.txt




Удалить пустые строки и комментарии из файла example.txt




sed '/ *#/d; /^$/d' example.txt




Удалить пустые строки и комментарии из файла example.txt




sed '/^$/d' example.txt




Удалить первую строку из файла example.txt




sed -e '1d' exampe.txt




Отобразить только строки содержащие string1




sed -n '/string1/p'




Удалить строку string1 из текста файла example.txt не изменяя всего остального




sed -e 's/string//g' example.txt




Удалить пустые символы в конце каждой строки файла example.txt




sed -e 's/ *$//' example.txt




Вывести пятую строку




sed -n '5p;5q' example.txt




Вывести строки со второй по пятую




sed -n '2,5p' example.txt




Заменить последовательность из любого количества нулей одним нулём




sed -e 's/00*/0/g' example.txt




Вывести отсортированное содержимое двух файлов




sort file1 file2




Вывести отсортированное содержимое двух файлов исключая повторные значения




sort file1 file2 | uniq




Вывести уникальные значения из отсортированного содержимого двух файлов




sort file1 file2 | uniq -u




Вывести только повторяющиеся значения из отсортированного содержимого двух файлов




sort file1 file2 | uniq -d




Перевести символы нижнего регистра в верхний




echo 'word' | tr '[:lower:]' '[:upper:]'



2022-08-08T00:48:58
Утилиты командной строки

jq Руководство

Программа 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’
Input12345678909876543212345
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) ‘
Input10000000000000000000000000000001
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»: «менее интересные данные»}
Output42




jq ‘.foo’
Input{«notfoo»: правда, «alsonotfoo»: ложь}
Outputnull




jq ‘.[«foo»]’
Input{«foo»: 42}
Output42




Необязательный индекс идентификатора объекта: .foo?




То же, что и .foo , но не выводит даже ошибку, когда . не является массивом или объектом.




Examples




jq ‘.foo?’
Input{«foo»: 42, «bar»: «менее интересные данные»}
Output42




jq ‘.foo?’
Input{«notfoo»: правда, «alsonotfoo»: ложь}
Outputnull




jq ‘.[«foo»]?’
Input{«foo»: 42}
Output42




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}]
Outputnull




jq ‘.[-2]’
Input[1,2,3]
Output2




Массив / фрагмент строки:. .[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[]
Outputnone




jq ‘.[]’
Input{«a»: 1, «b»: 1}
Output1
1




.[]?




Подобно .[] , Но если. не является массивом или объектом.




Comma: ,




Если два фильтра разделены запятой, то один и тот же ввод будет подаваться в оба, и потоки выходных значений двух фильтров будут объединены по порядку: сначала все выходные данные, созданные левым выражением, а затем все выходы. производится по праву. Например, фильтр .foo, .bar создает как поля «foo», так и поля «bar» как отдельные выходные данные.




Examples




jq ‘.foo,.bar’
Input{«foo»: 42, «bar»: «что-то еще», «baz»: правда}
Output42
«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’
Input1
Output15




Типы и значения




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}]]
Output1




Сборка операторов и функций




Некоторые операторы jq (например, + ) делают разные вещи в зависимости от типа своих аргументов (массивы, числа и т. Д.). Однако jq никогда не выполняет неявных преобразований типов. Если вы попытаетесь добавить строку к объекту, вы получите сообщение об ошибке и никакого результата.




Обратите внимание,что все числа преобразуются в представление IEEE754 двойной точности с плавающей точкой.Арифметические и логические операторы работают с этими преобразованными двойными числами.Результаты всех таких операций также ограничены двойной точностью.




Единственным исключением из этого поведения числа является снимок исходного литерала числа.Если число,которое изначально было представлено в виде литерала,никогда не изменяется до конца программы,то оно выводится на вывод в своей оригинальной литеральной форме.Это также включает случаи,когда исходный литерал будет усечен при преобразовании в число с плавающей точкой двойной точности IEEE754.




Addition: +




Оператор + берет два фильтра, применяет их к одному и тому же входу и складывает результаты вместе. Что означает «добавление», зависит от задействованных типов:




  • Числа складываются обычной арифметикой.
  • Массивы добавляются путем объединения в больший массив.
  • Строки добавляются путем объединения в более крупную строку.
  • Объекты добавляются путем слияния, то есть путем вставки всех пар ключ-значение из обоих объектов в один комбинированный объект. Если оба объекта содержат значение для одного и того же ключа, выигрывает объект справа от + . (Для рекурсивного слияния используйте оператор * .)




null может быть добавлен к любому значению и возвращает другое значение без изменений.




Examples




jq ‘.a+1’
Input{«a»: 7}
Output8




jq ‘.a+.b’
Input{«a»: [1,2], «b»: [3,4]}
Output[1,2,3,4]




jq ‘.a+null’
Input{«a»: 1}
Output1




jq ‘.a+1’
Input{}
Output1




jq ‘{a:1}+{b:2}+{c:3}+{a:42}’
Inputnull
Output{«a»: 42, «b»: 2, «c»: 3}




Subtraction: -




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




Examples




jq ‘4-.a’
Input{«a»:3}
Output1




jq ‘.-[«xml»,»yaml»]»
Input[«xml», «yaml», «json»]
Output[«json»]




Умножение, деление, по модулю: * , / и %




Эти инфиксные операторы ведут себя должным образом при наличии двух чисел. Деление на ноль вызывает ошибку. x % y вычисляет x по модулю y.




Умножение строки на число приводит к многократному объединению этой строки. "x" * 0 дает ноль .




Деление строки на другую делит первую строку,используя вторую в качестве разделителей.




Умножение двух объектов приводит к их рекурсивному слиянию:это работает как сложение,но если оба объекта содержат значение для одного и того же ключа,а значения являются объектами,то они объединяются по одной и той же стратегии.




Examples




jq ’10/.*3′
Input5
Output6




jq ‘./»,»‘
Input«а, б, в, г, д»
Output[«a»,»b,c,d»,»e»]




jq ‘{‘k’:{«a»:1,»b»:2}}*{«k»:{«a»:0,»c»:3}}’
Inputnull
Output{«k»: {«a»: 0, «b»: 2, «c»: 3}}




jq ‘.[]| (1/.)?’
Input[1,0,-1]
Output1
-1




length




Встроенная функция length получает длину различных типов значений:




  • Длина строки — это количество содержащихся в ней кодовых точек Unicode (которое будет таким же, как длина в байтах в кодировке JSON, если это чистый ASCII).
  • Длина массива — это количество элементов.
  • Длина объекта — это количество пар ключ-значение.
  • Длина нуля равна нулю.




Example




jq ‘.[]| length’
Input[[1,2], «строка», {«a»: 2}, ноль]
Output2
6
1
0




utf8bytelength




utf8bytelength функция utf8bytelength выводит количество байтов, используемых для кодирования строки в UTF-8.




Example




jq ‘utf8bytelength’
Input«u03bc»
Output2




keyskeys_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»]
Outputtrue
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)’
Inputnull
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»])’
Inputnull
Outputnull




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)’
Inputnull
Output{«а»: {«б»: 1}}




jq ‘setpath([«a»,»b»];1)’
Input{«a»:{«b»:0}}
Output{«а»: {«б»: 1}}




jq ‘setpath([0,»a»];1)’
Inputnull
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_entriesfrom_entrieswith_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}




arraysobjectsiterablesbooleansnumbersnormalsfinitesstringsnullsvaluesscalars




Эти встроенные модули выбирают только те входы,которые являются массивами,объектами,итерациями (массивами или объектами),булевыми числами,числами,нормальными числами,конечными числами,строками,нулевыми,ненулевыми значениями и неитерациями,соответственно.




Example




jq ‘.[]|numbers’
Input[[],{},1,»foo»,null,true,false]
Output1




empty




empty возвращает результатов. Вовсе нет. Даже не null .




Это полезно в некоторых случаях.Вы узнаете,если она вам понадобится 🙂




Examples




jq ‘1,пусто,2’
Inputnull
Output1
2




jq ‘[1,2,empty,3]’
Inputnull
Output[1,2,3]




error(message)




Выдает ошибку, точно так же, как .a применяется к значениям, отличным от null и объектов, но с заданным сообщением в качестве значения ошибки. Ошибки можно отловить с помощью try / catch; см. ниже.




halt




Останавливает программу jq без дальнейших выходов. jq выйдет со статусом выхода 0 .




halt_errorhalt_error(exit_code)




Останавливает программу jq без дальнейших выходов. Ввод будет напечатан на stderr как необработанный вывод (т. Е. Строки не будут иметь двойных кавычек) без оформления, даже без символа новой строки.




Данный exit_code (недобросовестный 5 ) будет статус выхода JQ в.




Например, "Error: somthing went wrongn"|halt_error(1) .




$__loc__




Создает объект с ключом «файл» и ключом «строка» с именем файла и номером строки, где встречается $__loc__ , в качестве значений.




Example




jq ‘try error(«($__loc__)»)catch .’
Inputnull
Output«{»file»:»<top-level>»,»line»:1}»




pathspaths(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]
Output6




jq ‘add’
Input[]
Outputnull




anyany(condition)any(generator; condition)




Фильтр any принимает в качестве входных данных массив логических значений и выдает на выходе значение « true если какой-либо из элементов массива является true .




Если ввод — пустой массив, any возвращает false .




Форма any(condition) применяет данное условие к элементам входного массива.




Форма any(generator; condition) применяет данное условие ко всем выходам данного генератора.




Examples




jq ‘any’
Input[true, false]
Outputtrue




jq ‘any’
Input[false, false]
Outputfalse




jq ‘any’
Input[]
Outputfalse




allall(condition)all(generator; condition)




Фильтр all принимает в качестве входных данных массив булевых значений, и производит true в качестве выходного сигнала , если все элементы массива являются true .




Форма all(condition) применяет данное условие к элементам входного массива.




Форма all(generator; condition) применяет данное условие ко всем выходам данного генератора.




Если вход является пустым массивом, all возвращает true .




Examples




jq ‘all’
Input[true, false]
Outputfalse




jq ‘all’
Input[true, true]
Outputtrue




jq ‘all’
Input[]
Outputtrue




flattenflatten(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)’
Inputnull
Output2
3




jq ‘[range(2;4)]’
Inputnull
Output[2,3]




jq ‘[range(4)]’
Inputnull
Output[0,1,2,3]




jq ‘[range(0;10;3)]’
Inputnull
Output[0,3,6,9]




jq ‘[range(0;10;-1)]’
Inputnull
Output[]




jq ‘[range(0;-5;-1)]’
Inputnull
Output[0,-1,-2,-3,-4]




floor




Функция floor возвращает нижний предел своего числового ввода.




Example




jq ‘floor’
Input3.14159
Output3




sqrt




Функция sqrt возвращает квадратный корень из входных числовых значений.




Example




jq ‘sqrt’
Input9
Output3




tonumber




Функция tonumber анализирует свой ввод как число. Он преобразует правильно отформатированные строки в их числовой эквивалент, оставит числа в покое и выдаст ошибку для всех остальных входных данных.




Example




jq ‘.[]| tonumber’
Input[1, «1»]
Output1
1




tostring




Функция tostring печатает ввод в виде строки. Строки остаются без изменений, а все остальные значения кодируются в формате JSON.




Example




jq ‘.[]| tostring’
Input[1, «1», [1]]
Output«1»
«1»
«[1]»




type




Функция type возвращает тип своего аргумента в виде строки, которая может быть пустой, логической, числом, строкой, массивом или объектом.




Example




jq ‘map(type)’
Input[0, ложь, [], {}, ноль, «привет»]
Output[«число», «логическое», «массив», «объект», «ноль», «строка»]




infinitenanisinfiniteisnanisfiniteisnormal




Некоторые арифметические операции могут давать бесконечные значения, а не числа (NaN). isinfinite встроенный возвращает true , если его вход бесконечен. isnan встроенный возвращает true , если его ввод является NaN. infinite встроенный возвращает положительное бесконечное значение. nan встроенный возвращает NaN. isnormal встроенный возвращает истину , если ее вход нормальный номер.




Обратите внимание,что деление на ноль приводит к ошибке.




В настоящее время большинство арифметических операций,работающих с бесконечностью,NaN и субнормалями,не вызывают ошибок.




Examples




jq ‘. [] | (бесконечное *.) <0 ‘
Input[-1, 1]
Outputtrue
false




jq ‘infinite,nan | type’
Inputnull
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}]]




minmaxmin_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]
Output2




jq ‘max_by(.foo)’
Input[{«foo»:1, «bar»:14}, {«foo»:2, «bar»:3}]
Output{«foo»:2, «bar»:3}




uniqueunique_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»
Outputtrue




jq ‘contains([«baz»,»bar»])’
Input[«foobar», «foobaz», «blarp»]
Outputtrue




jq ‘contains([«bazzzzz»,»bar»])’
Input[«foobar», «foobaz», «blarp»]
Outputfalse




jq ‘contains({foo:12,bar:[{barp:12}]})’
Input{«foo»: 12, «bar»:[1,2,{«barp»:12, «blip»:13}]}
Outputtrue




jq ‘contains({foo:12,bar:[{barp:15}]})’
Input{«foo»: 12, «bar»:[1,2,{«barp»:12, «blip»:13}]}
Outputfalse




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»
Output3




jq ‘rindex(«,»)’
Input«a,b, cd, efg, hijk»
Output12




inside




Фильтр inside(b) даст истину, если вход полностью содержится в b. По сути, это перевернутая версия файла contains .




Examples




jq ‘inside(«foobar»)’
Input«bar»
Outputtrue




jq ‘inside([«foobar»,»foobaz»,»blarp»])’
Input[«baz», «bar»]
Outputtrue




jq ‘inside([«foobar»,»foobaz»,»blarp»])’
Input[«bazzzzz», «bar»]
Outputfalse




jq ‘inside({«foo»:12,»bar»:[1,2,{«barp»:12,»blip»:13}]})’
Input{«foo»: 12, «bar»: [{«barp»: 12}]}
Outputtrue




jq ‘inside({«foo»:12,»bar»:[1,2,{«barp»:12,»blip»:13}]})’
Input{«foo»: 12, «bar»: [{«barp»: 15}]}
Outputfalse




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]




combinationscombinations(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_downcaseascii_upcase




Выдает копию входной строки с алфавитными символами (a-z и A-Z),преобразованными в указанный регистр.




while(cond; update)




Функция while(cond; update) позволяет многократно применять обновление к файлам . пока cond не станет ложным.




Обратите внимание, что while(cond; update) внутренне определяется как рекурсивная функция jq. Рекурсивные вызовы внутри while не будут потреблять дополнительную память, если update производит не более одного вывода для каждого ввода. См. Дополнительные темы ниже.




Example




jq ‘[в то время как (. <100;. * 2)]’
Input1
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]’
Input4
Output24




recurse(f)recurserecurse(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)’
Input2
Output2
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}}]




$ENVenv




$ENV — это объект, представляющий переменные среды, установленные при запуске программы jq.




env выводит объект, представляющий текущую среду jq.




На данный момент не существует встроенного модуля для установки переменных окружения.




Examples




jq ‘$ENV.PAGER’
Inputnull
Output«less»




jq ‘env.PAGER’
Inputnull
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]
Output0




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)» ‘
Input42
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 побега, путем отображения символов <>&'" их эквиваленты сущностей &lt; , &gt; , &amp; , &apos; , &quot; .




  • @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»
Output1425599507




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»
Output1425599507




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», «банан»]
Outputtrue
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’
Input2
Output«many»




>, >=, <=, <




Операторы сравнения > , >= , <= , < возвращают, является ли их левый аргумент больше, больше или равен, меньше или равен или меньше их правого аргумента (соответственно).




Порядок совпадает с описанным выше для sort .




Example




jq ‘. < 5’
Input2
Outputtrue




and/or/not




jq поддерживает обычные булевы операторы and/or/not.Они имеют тот же стандарт истинности,что и выражения if-false и null считаются «ложными значениями»,а все остальное-«истинным значением».




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




not на самом деле является встроенной функцией, а не оператором, поэтому он вызывается как фильтр, который может быть передан по конвейеру, а не со специальным синтаксисом, как в .foo and .bar | not .




Эти три оператора дают только значения «true» и «false»,поэтому они полезны только для настоящих булевых операций,а не для обычной идиомы Perl/Python/Ruby «значение_которое_может_быть_null или по умолчанию».Если вы хотите использовать эту форму «или»,выбирая между двумя значениями,а не оценивая условие,смотрите оператор «//» ниже.




Examples




jq ’42 и «строка»‘
Inputnull
Outputtrue




jq ‘(true,false)или false’
Inputnull
Outputtrue
false




jq ‘(true,true)и (true,false)’
Inputnull
Outputtrue
false
true
false




jq ‘[true,false | not]’
Inputnull
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}
Output19




jq ‘.foo //42’
Input{}
Output42




try-catch




Ошибки можно try EXP catch EXP с помощью try EXP catch EXP . Выполняется первое выражение, а если оно терпит неудачу, то выполняется второе с сообщением об ошибке. Вывод обработчика, если он есть, выводится так, как если бы это был вывод выражения, которое нужно попробовать.




Форма try EXP использует в качестве обработчика исключений empty строку.




Examples




jq ‘try .a catch «.не является объектом»‘
Inputtrue
Output«. не объект»




jq ‘[.[]|try .a]’
Input[{}, правда, {«а»: 1}]
Output[null, 1]




jq ‘try error(«какое-то исключение»)catch .’
Inputtrue
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»
Outputtrue




jq ‘.[]| test(«a b c#пробелы игнорируются»;»ix»)’
Input[«xabcd», «ABC»]
Outputtrue
true




match(val)match(regex; flags)




match выводит объект для каждого найденного совпадения. В матчах есть следующие поля:




  • offset — смещение в кодовых точках UTF-8 от начала ввода
  • length — длина совпадения в кодовых точках UTF-8
  • string — строка, которая соответствует
  • 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»
Output3




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}
Output210




jq ‘.as $i|[(.*2|.as $i| $i),$i]’
Input5
Output[10,5]




jq ‘.as [$a,$b,{c:$c}]| $a+$b+$c’
Input[2, 3, {«c»: 4, «d»: 5}]
Output9




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]
Output20




isempty(exp)




Возвращает true, если exp не производит выходных данных, иначе false.




Example




jq ‘isempty(empty)’
Inputnull
Outputtrue




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(.))]’
Input10
Output[0,9,5]




firstlastnth(n)




В first и last функции извлечения первого и последнего значения из любого массива в . .




Функция nth(n) извлекает n-е значение любого массива в . .




Example




jq ‘[range(.)]|[first,last,nth(5)]’
Input10
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) ‘
Inputnull
Output0
3
6
9




jq ‘def while (cond; update): def _ while: if cond then., (update | _ while) else empty end; _пока; [в то время как (. <100;. * 2)] ‘
Input1
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]])]’
Input1
Output[[[0],2],[[0]]]




fromstream(stream_expression)




Выводит значения,соответствующие выходам потокового выражения.




Example




jq ‘fromstream(1|truncate_stream([[0],1],[[1,0],2],[[1,0]],[[1]]))’
Inputnull
Output[2]




tostream




tostream встроенных выходов поточной формы его ввода.




Example




jq ‘.as $dot|fromstream($dot|tostream)|.==$dot’
Input[0,[1,{«a»:1},{«b»:2}]]
Outputtrue




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 Стивен Долан



2022-08-07T22:49:09
Утилиты командной строки

Timeout команды в Linux

timeoutэто утилита командной строки, которая запускает указанную команду и завершает ее, если она все еще выполняется по истечении заданного периода времени. Другими словами, timeoutпозволяет запустить команду с ограничением по времени. Эта timeoutкоманда является частью пакета основных утилит GNU, который установлен практически в любом дистрибутиве Linux.




Это удобно, когда вы хотите запустить команду, которая не имеет встроенной опции тайм-аута.




В этой статье мы объясним, как использовать команду Linux timeout.




Как использовать timeoutкоманду




Синтаксис timeoutкоманды следующий:




timeout [OPTIONS] DURATION COMMAND [ARG]…




Копировать




Может DURATIONбыть положительным целым числом или числом с плавающей запятой, за которым следует необязательный суффикс единицы измерения:




  • s— секунды (по умолчанию)
  • m— минут
  • h— часы
  • d— дней




Когда единицы измерения не используются, по умолчанию используются секунды. Если для длительности установлено нулевое значение, соответствующий тайм-аут отключен.




Параметры команды должны быть указаны перед аргументами.




Вот несколько основных примеров, демонстрирующих использование timeoutкоманды:




  • Завершить команду через пять секунд:timeout 5 ping 8.8.8.8Копировать
  • Завершить команду через пять минут:timeout 5m ping 8.8.8.8Копировать
  • Завершить команду через одну минуту и ​​шесть секунд:timeout 1.1m ping 8.8.8.8Копировать




Если вы хотите запустить команду, требующую повышенных привилегий, например tcpdump , добавьте sudo перед timeout:




sudo timeout 300 tcpdump -n -w data.pcap




Отправка определенного сигнала




Если сигнал не подан, timeoutотправляет SIGTERMсигнал управляемой команде, когда достигается лимит времени. Вы можете указать, какой сигнал отправлять, используя опцию -s( ).--signal




Например, чтобы отправить SIGKILLкоманду ping через одну минуту, вы должны использовать:




sudo timeout -s SIGKILL ping 8.8.8.8




Вы можете указать сигнал по имени, например SIGKILL, или по его номеру, например 9. Следующая команда идентична предыдущей:




sudo timeout -s 9 ping 8.8.8.8




Чтобы получить список всех доступных сигналов, используйте kill -l команду:




kill -l




Уничтожение зависших процессов




SIGTERM, сигнал по умолчанию, отправляемый при превышении лимита времени, может быть перехвачен или проигнорирован некоторыми процессами. В таких ситуациях процесс продолжает выполняться после отправки сигнала завершения.




Чтобы убедиться, что отслеживаемая команда уничтожена, используйте параметр -k--kill-after), за которым следует период времени. Когда эта опция используется после достижения заданного срока, timeoutкоманда отправляет SIGKILLуправляемой программе сигнал, который нельзя перехватить или проигнорировать.




В следующем примере timeoutкоманда выполняется в течение одной минуты, и если она не будет завершена, она будет уничтожена через десять секунд:




sudo timeout -k 10 1m ping 8.8.8.8




тайм-аут -k «./test.sh»




убит после достижения заданного срока




Сохранение статуса выхода




timeoutвозвращается 124, когда лимит времени достигнут. В противном случае он возвращает статус выхода управляемой команды.




Чтобы вернуть статус выхода команды даже при достижении лимита времени, используйте --preserve-statusопцию:




timeout --preserve-status 5 ping 8.8.8.8




Бег на переднем плане




По умолчанию timeoutзапускает управляемую команду в фоновом режиме. Если вы хотите запустить команду на переднем плане, используйте --foregroundопцию:




timeout --foreground 5m ./script.sh




Этот параметр полезен, когда вы хотите запустить интерактивную команду, требующую ввода данных пользователем.




Вывод




Команда timeoutиспользуется для запуска данной команды с ограничением по времени.




timeoutэто простая команда, которая не имеет большого количества опций. Обычно вы будете вызывать timeoutтолько с двумя аргументами: продолжительностью и управляемой командой.




Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.



2022-06-13T23:55:52
Утилиты командной строки

10 примеров команд lsof в Linux

10 примеров команд lsof в Linux. В этой статье мы рассмотрим команду lsof с практическими примерами. lsof расшифровывается как «LiSt Open Files» и используется для того чтобы понять, какие файлы открываются какими процессами. Как мы все знаем, Linux/Unix рассматривает все как файлы (в том числе каналы, сокеты, каталоги, устройства и т.д.). Одна из причин использования команды lsof – это ситуация когда диск не может быть размонтирован, так как возникает ошибка: “Файлы используются“. С помощью этой команды мы можем легко определить используемые файлы.




1. Вывод всех открытых файлов с помощью команды lsof




В приведенном ниже примере lsof в Linux будет показан список открытых файлов. В данном выводе отображаются такие столбцы, как CommandPIDUSERFDTYPE и т.д.




lsof







Разделы и их значения говорят сами за себя. Однако мы рассмотрим столбцы FD&TYPE более подробно:




FD – обозначает дескриптор файла и принимает следующие значения как:




  • cwd – текущий рабочий каталог
  • rtd – корневой каталог
  • txt – текст программы (код и данные)
  • mem  файл памяти




Кроме того, в столбцах FD такие номера, как 1u, являются фактическим дескриптором файла, а за ним следует один из флагов urw как режим доступа:




  • r – доступа для чтения.
  • w – доступа для записи.
  • u – чтения и записи.




TYPE – файлов и их идентификация:




  • DIR – директория
  • REG – обычный файл
  • CHR – специальный символьный файл.
  • FIFO – First In First Out




2. Список открытых пользовательских файлов




Приведенная ниже команда отобразит список всех открытых файлов пользователя sedicomm:




lsof -u sedicomm




3. Поиск процессов, работающих на конкретном порту




Чтобы узнать все запущенные процессы на определенном порту, просто используйте следующую команду с флагом -i. В приведенном ниже примере будут выведены все запущенные процессы порта 22:




# lsof -i TCP:22



COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

sshd 1471 root 3u IPv4 12683 0t0 TCP *:ssh (LISTEN)

sshd 1471 root 4u IPv6 12685 0t0 TCP *:ssh (LISTEN)




4. Вывод открытых файлов IPv4 и IPv6




В приведенном ниже примере lsof в Linux показаны только сетевые файлы IPv4 и IPv6, выведенные с помощью отдельных команд:




1# lsof -i 42​3COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME4rpcbind 1203 rpc # lsof -i 4



COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

rpcbind 1203 rpc 6u IPv4 11326 0t0 UDP *:sunrpc

rpcbind 1203 rpc 7u IPv4 11330 0t0 UDP *:954

rpcbind 1203 rpc 8u IPv4 11331 0t0 TCP *:sunrpc (LISTEN)

avahi-dae 1241 avahi 13u IPv4 11579 0t0 UDP *:mdns

avahi-dae 1241 avahi 14u IPv4 11580 0t0 UDP *:58600




# lsof -i 6



COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

rpcbind 1203 rpc 9u IPv6 11333 0t0 UDP *:sunrpc

rpcbind 1203 rpc 10u IPv6 11335 0t0 UDP *:954

rpcbind 1203 rpc 11u IPv6 11336 0t0 TCP *:sunrpc (LISTEN)

rpc.statd 1277 rpcuser 10u IPv6 11858 0t0 UDP *:55800

rpc.statd 1277 rpcuser 11u IPv6 11862 0t0 TCP *:56428 (LISTEN)

cupsd 1346 root 6u IPv6 12112 0t0 TCP localhost:ipp (LISTEN)




5. Вывод открытых файлов диапазона портов TCP 1-1024




Для вывода всех запущенных процессов открытых файлов TCP-порт меняется в диапазоне 1-1024.




# lsof -i TCP:1-1024



COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

rpcbind 1203 rpc 11u IPv6 11336 0t0 TCP *:sunrpc (LISTEN)

cupsd 1346 root 7u IPv4 12113 0t0 TCP localhost:ipp (LISTEN)

sshd 1471 root 4u IPv6 12685 0t0 TCP *:ssh (LISTEN)

master 1551 root 13u IPv6 12898 0t0 TCP localhost:smtp (LISTEN)

sshd 1834 root 3r IPv4 15101 0t0 TCP 192.168.0.2:ssh->192.168.0.1:conclave-cpp (ESTABLISHED)

sshd 1838 sedicomm 3u IPv4 15101 0t0 TCP 192.168.0.2:ssh->192.168.0.1:conclave-cpp (ESTABLISHED)

sshd 1871 root 3r IPv4 15842 0t0 TCP 192.168.0.2:ssh->192.168.0.1:groove (ESTABLISHED)

httpd 1918 root 5u IPv6 15991 0t0 TCP *:http (LISTEN)

httpd 1918 root 7u IPv6 15995 0t0 TCP *:https (LISTEN)




6. Исключение пользователей с использованием символа «^»




В этом примере lsof в Linux мы исключили пользователя root. Вы же можете исключить конкретного пользователя, используя «^» с командой приведённой ниже:




# lsof -i -u^root



COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

rpcbind 1203 rpc 6u IPv4 11326 0t0 UDP *:sunrpc

rpcbind 1203 rpc 7u IPv4 11330 0t0 UDP *:954

rpcbind 1203 rpc 8u IPv4 11331 0t0 TCP *:sunrpc (LISTEN)

rpcbind 1203 rpc 9u IPv6 11333 0t0 UDP *:sunrpc

rpcbind 1203 rpc 10u IPv6 11335 0t0 UDP *:954

rpcbind 1203 rpc 11u IPv6 11336 0t0 TCP *:sunrpc (LISTEN)

avahi-dae 1241 avahi 13u IPv4 11579 0t0 UDP *:mdns

avahi-dae 1241 avahi 14u IPv4 11580 0t0 UDP *:58600

rpc.statd 1277 rpcuser 5r IPv4 11836 0t0 UDP *:soap-beep

rpc.statd 1277 rpcuser 8u IPv4 11850 0t0 UDP *:55146

rpc.statd 1277 rpcuser 9u IPv4 11854 0t0 TCP *:32981 (LISTEN)

rpc.statd 1277 rpcuser 10u IPv6 11858 0t0 UDP *:55800

rpc.statd 1277 rpcuser 11u IPv6 11862 0t0 TCP *:56428 (LISTEN)




7. Узнайте, какие файлы и команды использует пользователь?




Приведенный ниже пример показывает, что пользователь sedicomm использует такие команды, как ping и /etc.




# lsof -i -u sedicomm



COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

bash 1839 sedicomm cwd DIR 253,0 12288 15 /etc

ping 2525 sedicomm cwd DIR 253,0 12288 15 /etc




8. Вывод списка всех сетевых подключений




Следующая команда с опцией «-i» выводит список всех сетевых подключений «LISTENING & ESTABLISHED»:




# lsof -i



COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

rpcbind 1203 rpc 6u IPv4 11326 0t0 UDP *:sunrpc

rpcbind 1203 rpc 7u IPv4 11330 0t0 UDP *:954

rpcbind 1203 rpc 11u IPv6 11336 0t0 TCP *:sunrpc (LISTEN)

avahi-dae 1241 avahi 13u IPv4 11579 0t0 UDP *:mdns

avahi-dae 1241 avahi 14u IPv4 11580 0t0 UDP *:58600

rpc.statd 1277 rpcuser 11u IPv6 11862 0t0 TCP *:56428 (LISTEN)

cupsd 1346 root 6u IPv6 12112 0t0 TCP localhost:ipp (LISTEN)

cupsd 1346 root 7u IPv4 12113 0t0 TCP localhost:ipp (LISTEN)

sshd 1471 root 3u IPv4 12683 0t0 TCP *:ssh (LISTEN)

master 1551 root 12u IPv4 12896 0t0 TCP localhost:smtp (LISTEN)

master 1551 root 13u IPv6 12898 0t0 TCP localhost:smtp (LISTEN)

sshd 1834 root 3r IPv4 15101 0t0 TCP 192.168.0.2:ssh->192.168.0.1:conclave-cpp (ESTABLISHED)

httpd 1918 root 5u IPv6 15991 0t0 TCP *:http (LISTEN)

httpd 1918 root 7u IPv6 15995 0t0 TCP *:https (LISTEN)

clock-app 2362 narad 21u IPv4 22591 0t0 TCP 192.168.0.2:45284->www.gov.com:http (CLOSE_WAIT)

chrome 2377 narad 61u IPv4 25862 0t0 TCP 192.168.0.2:33358->maa03s04-in-f3.1e100.net:http (ESTABLISHED)

chrome 2377 narad 80u IPv4 25866 0t0 TCP 192.168.0.2:36405->bom03s01-in-f15.1e100.net:http (ESTABLISHED)




9. Поиск по PID




В приведенном ниже примере показано только те выводы, чей PID равен 1:




# lsof -p 1



COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

init 1 root cwd DIR 253,0 4096 2 /

init 1 root rtd DIR 253,0 4096 2 /

init 1 root txt REG 253,0 145180 147164 /sbin/init

init 1 root mem REG 253,0 1889704 190149 /lib/libc-2.12.so

init 1 root mem REG 253,0 142472 189970 /lib/ld-2.12.so




10. Завершение всей активности конкретного пользователя




Иногда вам может потребоваться завершить все процессы для конкретного пользователя. Команда ниже завершает все процессы пользователя sedicomm:




# kill -9 `lsof -t -u sedicomm`




Примечание: здесь невозможно привести пример всех доступных опций, это руководство знакомит вас, как можно использовать команду lsof. Вы можете обратиться к странице справки команды lsof, чтобы узнать больше: man lsof.




Источник: https://blog.sedicomm.com/2020/03/19/10-primerov-komand-lsof-v-linux/



2022-04-23T02:29:41
Утилиты командной строки

Bash-скрипты

Сегодня поговорим о bash-скриптах. Это — сценарии командной строки, написанные для оболочки bash. Существуют и другие оболочки, например — zsh, tcsh, ksh, но мы сосредоточимся на bash. Этот материал предназначен для всех желающих, единственное условие — умение работать в командной строке Linux.

Сценарии командной строки — это наборы тех же самых команд, которые можно вводить с клавиатуры, собранные в файлы и объединённые некоей общей целью. При этом результаты работы команд могут представлять либо самостоятельную ценность, либо служить входными данными для других команд. Сценарии — это мощный способ автоматизации часто выполняемых действий.

Читать

Полезные команды Linux

Источник: https://unixhost.pro/clientarea/knowledgebase/30/poleznye-komandy-linux.html



2021-08-17T16:59:42
Утилиты командной строки