jq命令语法总结

一、常见用法

1. 基本类型

  • 字符串
#length,计算字符串的长度
jq '.name|length' tmp5.txt
#startswith,判断前缀
jq '.name|startswith("Ja")' tmp5.txt
#startswith,判断后缀
jq '.name|endswith("ck")' tmp5.txt
#contains,判断是否包含子串
jq '.name|contains("ac")' tmp5.txt
#相等判断==
jq '.name=="Red"' tmp5.txt
#utf8的字节长度
jq '.name|utf8bytelength' tmp5.txt
#将字符串按分隔符转换成数组split
echo '{"str":"a,b,c","key":"value"}' | jq '.str|split(",")'
#将字符串数组拼接成字符串,join
jq '.friends|map(.name)|join(",")' tmp5.txt
#字符串转数字tostring,本身字符串无影响
jq '.age|tonumber' tmp5.txt
#############字符操作####
#取连续子数组(含头不含尾)
jq '.city[0][0:3]' tmp5.txt
#开区间(含头不含尾),前3
jq '.city[0][:3]' tmp5.txt
#开区间(含头不含尾),后2
jq '.city[0][-2:]' tmp5.txt
#字符串拼接,常量要用双引号隔开
jq '"hello,"+.name' tmp5.txt
#
  • 数值
#length,返回本身
jq '.name|length' tmp5.txt
#逻辑判断,返回bool
jq '.age > 18' tmp5.txt
jq '.age == 18' tmp5.txt
jq '.age < 18' tmp5.txt
#数字转字符串tonumber,本身数值无影响
echo '{"age":"18","name":"Jack"}' | jq '.age|tostring'
#向上取整
echo '{"price":12.1}' | jq '.price|ceil'
#向下取整
echo '{"price":12.1}' | jq '.price|floor'
#加法兼容空
echo '{"a": 1}' | jq '.a+null'
echo '{}' | jq '.a+1'
  • 布尔值

any基于布尔数组,判断是否有true

any基于布尔数组,判断是否全部为true

echo '[true, false]'|jq 'all'
echo '[true, true]'|jq 'all'
echo '[true, false]'|jq 'any'
echo '[false, false]'|jq 'any'

2. json对象

  • 构建

构建时kv可以采用多种方式:

  1. 直接取根对象直属的子kv名称不变,则直接引用k即可,如{age}
  2. k需要换名称,或v的表达式不是直属子kv,则需显式定义kv对,如{“friend”:.friends[0]}、{“address”:.city}
  3. 直接构建常量,如{“sex”:“1”}

示例:

jq '{age,"sex":"1",city,"friend":.friends[0]}' tmp5.txt
  • 直接将value当作key

用括号包住表达式即可

jq '{(.name):.age}' tmp5.txt
  • 是否存在某个属性

select结果是Json对象,如果满足条件返回当前对象,如果不满足什么都不返回

has结果是boolean,返回值是true/false

#不存在某个属性就返回当前对象,否则什么都不返回
jq '.|select(.sex == null)' tmp5.txt 
#存在某个属性就返回当前对象,否则什么都不返回
jq '.|select(.sex != null)' tmp5.txt 
#是否存在某个属性
jq '.|has("sex")' tmp5.txt
  • 获取所有属性名称
#key按自然正序
jq '.|keys' tmp5.txt
#key按原来的顺序
jq '.|keys_unsorted' tmp5.txt
  • 获取属性个数

两个语法结果是一样的

jq '.|keys|length' tmp5.txt
jq '.|length' tmp5.txt
  • 属性链式获取
jq '.father.name' tmp5.txt
#链式中间的对象不存在不会报错,最终结果为null
jq '.mother.name' tmp5.txt
#搜索根所有后代节点,key为执行名称的值,结果是一个对象流(迭代器)
jq '..|.name?' tmp5.txt
  • 删除属性
#删除一个属性
jq '.|del(.friends)' tmp5.txt
#删除多个属性
jq '.|del(.friends,.city)' tmp5.txt
  • 添加属性

属性只能基于常量,不能基于表达式,如果需要添加对象属性,请参考修改属性值

jq '.friends[0]+{"version":"1.0"}' tmp5.txt 
  • 修改属性值

如果修改的属性原来有,

返回值是修改值前表达式的对象

运用多命令,可以同时设置多个属性

#子属性设置
jq '.|.name="Jack2"' tmp5.txt
#嵌套设置
jq '.|.father.age="49"' tmp5.txt
#整个对象整体替换
jq '.|.father={"name":"SuperJack","age":46}' tmp5.txt
#如果修改的属性不存在,则相当于添加
jq '.|.mother={"name":"Marry","age":46}' tmp5.txt 

3. 集合

  • 构建
#基于常量
jq '[1,2,3,4,5]' tmp5.txt
#基于表达式
jq '.friends' tmp5.txt 
#各元素基于表达式
jq '[.name,.friends[0].name,"Black"]' tmp5.txt
#基于对象流重组成集合
jq '[.friends[]|{name,age}]' tmp5.txt
  • 按index获取元素
#取index位置单个元素(从0开始)
jq '.city[1]' tmp5.txt
#取index位置多个元素(从0开始)
jq '.city[1,3,5]' tmp5.txt
#倒序取数据(从-1开始)
jq '.city[-1]' tmp5.txt
jq '.city[-1,-3]' tmp5.txt
#取连续子数组(含头不含尾)
jq '.city[0:3]' tmp5.txt
#开区间(含头不含尾),前3
jq '.city[:3]' tmp5.txt
#开区间(含头不含尾),后2
jq '.city[-2:]' tmp5.txt
  • 集合查询
#长度
jq '.city|length' tmp5.txt
#判断是否有第index+1号元素
jq '.friends|has(1)' tmp5.txt
#集合元素倒转
jq '.city|reverse' tmp5.txt
#自然排序(按元素值或第一个属性排序)
jq '.city|sort' tmp5.txt
jq '.friends|sort' tmp5.txt
#按表达式排序
jq '.city|sort_by(.|length)' tmp5.txt
jq '.friends|sort_by(.name)' tmp5.txt 
#按元素值排序去重
jq '.city|unique' tmp5.txt
#按指定表达式排序去重
jq '.friends|unique_by(.age)' tmp5.txt
#去重复元素
echo '[1,2,5,3,5,3,1,3]'| jq 'unique'
#按表达式聚合unique_by
echo '[{"foo": 1, "bar": 2}, {"foo": 1, "bar": 3}, {"foo": 4, "bar": 5}]'|jq 'unique_by(.foo)'
#contains,子串包含就行
echo '["foobar", "foobaz", "blarp"]'|jq 'contains(["baz", "bar"])' 
  • 聚合
#add聚合,对数字集合各元素求和
jq '.friends|map(.age)|add' tmp5.txt
#group_by将集合按表达式分成子组
echo '[{"foo":1, "bar":10}, {"foo":3, "bar":100}, {"foo":1, "bar":1}]'|jq 'group_by(.foo)'
#min/max,数字数组
echo '[5,4,2,7]'|jq 'min'
  • 集合操作
#两个集合用+操作,结果为拼接的集合
echo '{"a": [1,2,3], "b": [3,4]}'|jq '.a+.b'
#两个集合用-操作,结果为差集
echo '["xml", "yaml", "json"]'|jq '. - ["xml", "yaml"]'
  • 转换

map函数,接收一个集合作为入参,对每个元素进行函数转换,转换结果结果再构成新的数组

map_values函数(待补充)

#map转换结果组合新集合
jq '.friends|map(.age)' tmp5.txt
  • 数组打平

flatten不限深度打平,形成数组

flatten(n)打平形成数组,打平深度为n

echo '[1, [2], [[3]]]'|jq 'flatten'
echo '[1, [2], [[3]]]'|jq 'flatten(1)'
#对象也可以打平
echo '[{"foo": "bar"}, [{"foo": "baz"}]]'|jq 'flatten'

4. 对象流

或者叫做迭代器iterator,和集合的区别是:只有对象流的Json对象才能整体遍历操作,Json数组不行

Json数组是过程量,要想对Json数组每个元素进行操作必须先转换成对象流

  • 构建
#只能基于表达式,将数组转换成对象流
jq '.friends[]' tmp5.txt
#构建时迭代
jq '{name,"val":.city[]}' tmp5.txt 
  • 修改

  • 删除

  • 过滤

格式:select(conditon), 在conditon表达式中把遍历的元素当成根对象

select本质是只能作用于对象, 相当于filter,满足条件的对象返回,不满足忽略

#选择年龄为19的元素
jq '.friends[]|select(.age==19)' tmp5.txt 
#选择名字为White的元素
jq '.friends[]|select(.name=="White")' tmp5.txt 
#选择年龄大于18的元素
jq '.friends[]|select(.age>18)' tmp5.txt 
#选择年龄大于等于18的元素
jq '.friends[]|select(.age>=18)' tmp5.txt 
  • 按类型过滤(内置函数)

arrays, objects, iterables, booleans, numbers, normals, finites, strings, nulls, values, scalars

jq '.friends[]|objects' tmp5.txt
jq '.friends[]|arrays' tmp5.txt
  • 空兼容

.[]?.[]作用是一样的,但是如果对象流不存在时前者不会报错(什么都不返回),后者会报错(null不能被遍历)

jq '.teachers[]?|select(.age>=18)' tmp5.txt
jq '.teachers[]|select(.age>=18)' tmp5.txt

5. 逻辑运算

#相等判断
echo '[1, 1.0, "1", "banana"]' | jq '.[]|.==1'
#比较
echo 2 | jq '. > 1'
echo 2 | jq '. >= 1'
echo 2 | jq '. < 1'
echo 2 | jq '. <= 1'
#and or not
echo 2 | jq '.<3 and .>1'
echo 2 | jq '.<2 and .<1'
echo 2 | jq '.<2|not'
#表达式的值是否在另一个对象中作为key,相当于keys.contains
jq '.name|in({"Jack":18})' tmp5.txt

6. 算术运算

#加减乘除、取模
jq '(.age+2)*5' tmp5.txt
jq '.friends[]|(.age%10)' tmp5.txt

7. 同时执行多个命令

各表达式用逗号分开即可,返回值按执行顺序依次返回

jq '.name,.city' tmp5.txt

8. 工具函数

type: 获取数据类型

类型有:number,string,object,array

jq '.name|type' tmp5.txt
jq '.age|type' tmp5.txt
jq '.father|type' tmp5.txt
jq '.city|type' tmp5.txt 

range: 生成序列

#生成0到age的序列
jq '.age|range(.)' tmp5.txt
#步长为1,从3到age
jq '.age|range(3;.)' tmp5.txt
#步长为2,从3到age
jq '.age|range(3;.;2)' tmp5.txt

@base64/@base64d编解码

jq '.name|@base64' tmp5.txt
jq '.name|@base64|@base64d' tmp5.txt

9. 命令

while(cond; update) 循环

echo '1'|jq '[while(.<100; .*2)]' 

if分支判断

echo 2 | jq 'if . == 0 then "zero" elif . == 1 then "one" else "many" end'

二、其他用法

1.支持在表达式中使用变量

#设置基本类型的变量,一个变量用用一个`--arg`
jq --arg k1 v1 --arg k2 v2 '{name:.name,age:.age,env:$k1,env2:$k2}' tmp5.txt
#设置变量为json对象
jq --argjson k1 '{"p1":"v1"}' --arg k2 v2 '{age:.age,env:$k1.p1,env2:$k2}' tmp5.txt
#json对象流作为文件内容,运行时会将对象流构成数组并赋值为变量,示例内容为:{"name":"Jack"}{"name":"Red"}
jq --slurpfile a variableArr.txt  --arg k2 v2 '{age:.age,env:$a[0],en2:$a[1]}' tmp5.txt

2.输出线结果时,所有对象的字段按key排序输出

jq --sort-keys '.' tmp5.txt

三、踩坑

  • jq语法不支持数字为key

jq只能已string为key,数字为key的不支持。(fastjson支持)

{
  1102402202301:{
   "name":"盲盒至尊98",
   "inventory": 1
 },
 1102402202302:{
   "name":"盲盒至尊99",
   "inventory": 2
 }
}

四、示例文件tmp5.txt

{
  "age": 18,
  "name": "Jack",
  "father": {
    "age": 48,
    "name": "Link"
  },
  "city": [
    "ShangHai",
    "BeiJing",
    "GuangZhou",
    "ChangSha",
    "XiAn",
    "ChongQing",
    "GuiZhou",
    "SuZhou"
  ],
  "friends": [
    {
      "age": 16,
      "name": "Amy",
      "stars": 7
    },
    {
      "age": 15,
      "name": "Red",
      "stars": 8
    },
    {
      "age": 19,
      "name": "John",
      "stars": 9
    },
    {
      "age": 18,
      "name": "Tom",
      "stars": 8
    },
    {
      "age": 20,
      "name": "Bob",
      "stars": 7
    },
    {
      "age": 19,
      "name": "White",
      "stars": 9
    }
  ]
}
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值