Linux JQ 命令学习笔记

本文详细介绍了JQ命令行工具的使用,包括基础过滤器、内置运算符、条件判断和高级特性,如变量、reduce操作,帮助读者掌握在处理JSON数据时的高效操作技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      

目录

0. Prefice(前言)

1. Filter(过滤器)   

2. Options(可选项)

3. Basic Filters(基础过滤器)

4. Types And Values(数据类型和值)

5. Builtin Operators And Functions(内置运算符和函数)

6. Conditionals And Comparisons(条件和比较)

7. Advanced Features(高级特性)

8. 参考文档:


0. Prefice(前言)

JQ是一个命令行工具,主要用于处理json文本。语法很简单,如下:

jq [options...] filter [files...]

        JQ可以对json文本执行多种操作,包括选择、遍历、删减等等。例如 jq ´map(.price) | add´ 表示遍历输入的数组,并将其中每个元素的price累加起来。默认情况下,jq从stdin中读取json数据流,多个数据流使用空格分隔。还有一些命令行参数,主要用于控制输出和输出的格式,filter是jq语言编写的,主要用于操作输入的数据。

1. Filter(过滤器)   

        filter 相当于jq程序,有很多内置的filter用于从对象中提取字段、或者将一个数字转换为字符串或者其它的功能。

        filter 可以用不同的方式组合,比如可以通过管道将一个filter的输出当做另一个filter的输入,或者收集一个filter的输出,存到一个数组里。有些filter能够生成多个结果,比如枚举出json数组中的每个元素,通过管道将元素依次传输给第二个filter。其它语言中通过循环和迭代实现的功能在jq中可以通过组合多个filter来实现。

2. Options(可选项)

--slurp/-s:

        如果有多个json输入流,默认情况下,会对每个输入执行JQ命令,如果使用该参数,则会将所有输入放到一个数组里,然后执行一次JQ命令。

--raw-input/-R
默认情况下,输入必须是json格式文本,如果使用该选项,则将每行文本当做一个普通的字符串。

--null-input/-n 
将null作为输入,该选项忽略任何输入,仅仅将null当做输入传给filter。正如下面的例子,如果没有null-input,这时候第一个参数是"one",因为没有任何操作会被忽略,"inputs"表示剩余的输入,因此第一个用例输出"two, three",如果使用了null-input,这时候忽略的就是参数null,其余输入就会被读取到"inputs"里面,如示例三。

--compact-output / -c:
默认情况下,jq 的输出是可读性好的格式,如果使用该选项,则输出则会变得紧凑。

--colour-output / -C
默认情况下,如果输出到stdout,是有颜色的。使用该选项可以强制输出颜色,即便是输出到管道或者文件中。

--monochrome-output / -M
禁止输出颜色

--ascii-output / -a:
非ASCII字符通常当做utf8字符输出,使用该选项可以强制输出ascii字符。

--raw-output / -r
如果输出是一个字符串,默认情况下对包含一对双引号,如果使用该选项,则仅仅输出字符串文本。

--arg name value
传递变量到jq程序里

3. Basic Filters(基础过滤器)

'.'
   . 是最基本的过滤器,对输出不做任何处理,原样输出。通常用来输出一些可读性强的格式。

.Attr
   Attr是JSON对象的属性名,这个过滤器用于打印指定key的值,如果不存在对应的key,则输出NULL

.[]
    打印数组内容,括号内可以指定索引或者指定范围,索引从0开始。


,
    可以使用逗号连接多个过滤器,这种情况下,每个过滤器分别执行,结果也会并列展示出来

|
    管道符用于连接两个过滤器,功能上类似与Unix shell 管道,左侧过滤器执行结果会被当做右侧过滤器的输入,如果左侧过滤器产生多个结果,则右侧过滤器会分别执行。

4. Types And Values(数据类型和值)

    jq支持和json一致的数据集,包括数字、字符串、布尔值、数组、对象和null

数组 []
    和json一样,[]也用于构造一个数组,数组的元素可以是任意的jq表达式,表达式的结果将会组成一个数组,可以使用[]构造任何数组。

对象·{}
    和json一样,{}用于构造对象,如果对象的key是大小写敏感的,则双引号可以省略,值可以是任意的jq表达式(如果是复杂的表达式,还需要使用括号括起来),可以使用这个符号从输入中选取指定的字段。如果某个表达式生成多个结果,则对象也可能生成多个。如果key被括号括起来,则key也会被当做一个表达式。

5. Builtin Operators And Functions(内置运算符和函数)

         一些jq操作符(例如+),对根据参数的不同执行不同的操作(比如数组、数字、字符串等)。但是jq不会执行任何隐式的类型转换,如果两个参数类型不一致,会直接报错。

加号 +
    加号需要两个filter,输入会分别被过滤器执行,输出结果会根据过滤器结果类型相加起来。
    如果是数字,则按照算数相加。


    如果是数组,则会拼接成一个大数组,


    如果是字符串,则会拼接起来。


    如果是对象,则对象会被合并,如果有相同的key,则以右侧的过滤器中的key为最终结果。


    如果有一个结果是null,则返回另一个结果。

减号 - 
    和算术减法类似,减号也可以用在数组上,用于将数组1中所有在数组2中出现的元素删除。

乘法*、除法 /、取余%
    这些操作符只作用于数字。


length
    该函数获取不同类型值的长度。
    如果是字符串,则输出unicode代码点数量。也可以使用utf8bytelength 输出字符数量


    如果是数组,则输出数组元素个数


    如果是对象,则输出key-value 组的个数


    如果是null,则为0

 

keys
    如果输入是个对象,则输出一个包含该对象所有key的数组。


    如果输入是个数组,则输出该数组合法的索引。

has
    has函数返回一个对象是否有指定的key,或者一个数组在指定的索引上是否含有元素。

to_entries, from_entries, with_entries
    这些函数在对象和包含key-value的数组中转换,如果to_entries接受一个对象,则对于对象中每一个k:v,则输出的数组中将包含{"key": k, "value": v}.

from_entries 正好做相反的事情,with_entries 等价于 to_entries|map(foo)|from_entries

select
    select(filter),如果filter返回true,则结果与输入一致,否则不输出。

empty
    empty不返回任何结果,包括null也不返回。

map(filter)
    map是个遍历操作,对输出数组的每个元素执行filter,并将输出放到一个数组里。等价于 '.[]|filter'

 add
    add函数将输入当做一个数组,根据数组的元素类型执行相应的操作,包括累加、字符串拼接、合并等。

 range
    range函数用于生成一组连续的数字,range(4;10)产生6个数字,从4开始,直到10(10本身不包括在内)。生成的数组将作为独立的输出。

 tonumber
    这是个类型转换函数,该函数将输入当做数字,如果输入不是标准的数字形式会报错。

tostring
    同上,也是个类型转换函数,将输入当做字符串。

type
    该函数将输入的类型当做字符串输出,可能是null,boolean、number、string、array、object的一种。

 sort、sort_by
    这是个排序函数,输入必须是数组类型。sort_by用于根据某一个字段来排序或者基于filter,sort_by(filter)会根据filter结果来进行排序。

group_by(.attr)
    分组,类似于mysql,将输入当做一个数组,指定一个属性,具有相同值的会被分到同一个数组中。


    
min, max, min_by, max_by
    前两个就是取最大值和最小值,后两个可以根据指定属性取。

unique
    该函数输入是一个数组,输出一个不含重复元素的数组

reverse
    函数用于将数组翻转

contains(v)
    如果输入包含v,则该函数返回true。


recurse
    该函数主要用于搜索递归类型结构数据。

字符串替换 \(x)
    在一个字符串中,可以加入一个反斜杠开头的表达式:'\express',则这个表达式的结果将会插入到字符串中。

6. Conditionals And Comparisons(条件和比较)

== , !=
    表达式==只有在两个参数完全相等时才返回true,其他情况返回FALSE,表达式!=与之相反。

if-then-else
    表达式必须明确返回true或者FALSE,如果表达式返回false或者null会被当做false,如果返回0也是false.

>、>=、<=、<
    这几个比较运算符和算术比较运算符逻辑类似,结果返回true或者false

and/or/not
    布尔运算符,这里值得注意的地方是如果有一个操作数生成了多个结果,则运算符会针对每个结果运算一遍。

替代运算符 //
    如果一个过滤器表达式以 a//b的形式出现,如果a的结果不是false和null,则该过滤器结果为a的结果,否则为b表达式的结果。这个表达式对于提供默认值非常有用。

7. Advanced Features(高级特性)

         在其它编程语言中,变量是不可或缺的一部分。在JQ中,变量属于一种高级特性。在大部分语言里,变量是传递临时数据的唯一方式,如果你要计算一个值,并且之后在其它地方还要用到,你需要使用变量来存储它。为了给程序的其它函数传递值,你需要定义一个变量(作为函数参数等)。在jq中变量很少使用,但是也是可以定义的,主要用于定义一些标准库(很多jq函数就是这么实现的,比如map和find)。
    jq还有一个reduce操作,很强大但是使用起来需要一点技巧。这个操作主要用于jq内部操作。

    在jq中,我们可以使用表达式 exp as $x | .... 的方式来定义变量。对于exp生成的每一个值,都会单独执行后续的操作,这里的as就像一个遍历操作。
    除了定义变量外,还可以使用def 语法定义函数。
    reduce语法主要用于累积表达式生成的所有结果。

8. 参考文档:

1. 官方文档 https://stedolan.github.io/jq/manual/

2. https://linuxcommandlibrary.com/man/jq#assignment

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值