linux shell

关注公众号 jb51net

关闭
首页 > 脚本专栏 > linux shell > JSON命令jq使用

处理JSON最强命令jq使用场景

作者:2021不再有雨

jq命令是处理json字符串的神器, 主要用于获取JSON属性/简单重组JSON字符串,本章详细介绍jq的主要应用场景,感兴趣的朋友跟随小编一起看看吧

史上最全jq命令使用详解

一. 前言

本文价值千金, 阅读前请先收藏.

jq命令是处理json字符串的神器, 主要用于获取JSON属性/简单重组JSON字符串.

本章将详细介绍jq的主要应用场景, 帮助大家在平时工作中处理JSON的效率大大提升.

二. 语法

jq本身有一套完整语法,如要详细掌握参考另外一篇总结 jq详细语法参考

1. 使用语法

jq 表达式 处理源

处理源可以为文件路径或管道: 读取后必须为JSON对象, JSON数组, JSON对象流三类

2. 概念理解

JSON对象

{开头, 以}结尾的JSON字符串, 形如{}示例:

{
  "productId": "2048200008352211",
  "productName": "COACH蔻驰佩利系列 马车标识米兰编织链石英表"
}

JSON数组

[开头, 以]结尾的JSON字符串, 元素间用,分隔包括基本数组和JSON对象数组, 形如[{},{},{}]

基本数组: 元素为基本数据类型, 如[1,2,3,5], [“shanghai”, “guangzhou”,“beijing”]JSON对象数组: 元素为JSON对象, 略

JSON对象流

{
  "productId": "2048200008352211",
  "productName": "COACH蔻驰佩利系列 马车标识米兰编织链石英表"
 } 
{
  "productId": "2048200008352212",
  "productName": "COACH蔻驰佩利系列 马车标识米兰编织链石英表2"
 }
{
  "productId": "2048200008352213",
  "productName": "COACH蔻驰佩利系列 马车标识米兰编织链石英表3"
 }

根对象

是指jq命令当前处理的处理源的表达式引用, 在表达式中用.来表示

表达式/路径

jq命令是基于表达式输出结果的, 表达式可以通过.来访问子属性或子对象表达式的语法, 类似ognl表达式(对象导航语言)如.order.address.city表示获取当前处理源order(子对象)下的address(子对象)的city属性

{
  "uid": 11603,
  "mobile": "172****1333",
  "order": {
    "address": {
      "province": "上海市",
      "city": "海市",
      "distict": "浦东新区",
      "line": "广兰路地铁站1号口"
    },
    "items": [
      {
        "itemId": 123,
        "itemName": "无人机1"
      },
      {
        "itemId": 124,
        "itemName": "无人机2"
      }
    ]
  }
}

三. 主要用法

本文示例文件json.txt, 在文章最后

1. 常见表达式含义

. : 放在表达式开头, 用来表示.根对象, 也可用在属性之间作为访问路径的连接

.name: 输出指定属性,使用.连接的路径访问字段, 路径可用多层, 如order.items[0].itemId

.[下标] : 输出单个指定index的数组元素(从0开始)

.[下标1,下标2,..] : 输出多个指定数组元素, 结果为JSON对象流

express[] : 表达式expressJSON数组, 后面跟[]表示将express表示的JSON对象数组转换成JSON对象流, 形如: [{},{},{}]转换成{}{}{}

[表达式] : 将JSON对象流组合成JSON对象数组,形如: {}{}{}组装成[{},{},{}]

注意:

要想对JSON对象数组每个元素进行处理, 必须先转换成JSON对象流

2. 基本使用场景

jq '.' json.txt – 格式化

jq '.[0].address.city' json.txt --获取指定字段的值(可嵌套)

jq '.[0].name,.[0].url' json.txt --使用逗号分隔,取多个字段的值;返回值以换行分隔

jq '.[0].arrayBrowser[0]' json.txt --提取数组的单个元素

jq '.[0].arrayBrowser[0,1]' json.txt --提取数组的多个元素

jq '.[0].arrayBrowser[]' json.txt – 提取数组的全部元素转换成JSON对象流

jq '[.data.results[]|{topicId,viewCount}]' hjsource.json – 提取数组的指定属性

jq '[.data.results[]|{id:topicId,count:viewCount}]' hjsource.json – 提取数组的指定属性并重命名

注意:

上述最后两个示例先将JSON对象数组转化成JSON对象流, 再对各元素进行处理, 再组装成JSON对象数组

3. 重组

场景: 重组成对象

使用方法一: 组装时仅复用value

jq '{simpleName:.[0].name,postUrl:.[0].url}' json.txt , 得到结果 :

{
  "simpleName": "脚本之家",
  "postUrl": "//www.jb51.net"
}

比较下和jq '.[]|{simpleName:.name,postUrl:.url}' json.txt 的区别.

(前者处理单个对象, 后者处理JSON对象流)

2.使用方法二: 组装时复用整个key-value

运行jq '.[0]|{name,url}' json.txt , 得到结果:

{
  "name": "脚本之家",
  "url": "//www.jb51.net"
}

比较下和 jq '.[]|{name,url}' json.txt 的区别.

(前者处理单个对象, 后者处理JSON对象流)

注意:

引用的key-value可以是基本属性节点, 也可以是对象节点.

如运行jq '.[0]|{name,address}' json.txt

复用key-value时表达式前面没有.前缀, 仅复用value时才有.前缀

,分隔的多个表达式没必要任何关系, 层次也可不一样

场景: 重组成数组

在表达式外边套上[], 即可组装成数组. 根据组合元素的不同, 可以分以下三类:

1.重组元素为基本属性

运行 jq '[.[0].name,.[0].url]' json.txt, 得到结果:

[
  "脚本之家",
  "//www.jb51.net"
]

2.重组元素为单个json对象

运行 jq '[.[0].address]' json.txt , 得到结果:

[
  {
    "city": "厦门",
    "country": "中国"
  }
]

运行 jq '[.[0].arrayBrowser]' json.txt , 得到结果:

[
  [
    {
      "name": "Google",
      "url": "http://www.google.com"
    },
    {
      "name": "Baidu",
      "url": "http://www.baidu.com"
    }
  ]
]

3.重组元素为JSON对象流

jq '[.[]|.arrayBrowser[]]' json.txt, 得到结果:

[
  {
    "name": "Google",
    "url": "http://www.google.com"
  },
  {
    "name": "Baidu",
    "url": "http://www.baidu.com"
  },
  {
    "name": "360",
    "url": "http://www.so.com"
  },
  {
    "name": "bing",
    "url": "http://www.bing.com"
  }
]

4. 管道的使用

管道|的作用, 把管道前的处理结果作为管道后面处理的输入. 相当于管道前后各运行一次jq命令. (管道可以多次使用)

用法和前面的没有区别. 略

5. 内置函数的使用获取json对象的所有key组成的数组

命令格式: jq keys , 表达式只能是keys , 不能包含其他语法, 如果需要获取嵌套对象keys, 通过管道即可.

运行 jq '.[0]|keys' json.txt , 得到结果:

[
  "address",
  "arrayBrowser",
  "name",
  "url"
]

获取length

命令格式: jq length , 表达式只能是length , 不能包含其他语法, 如果需要获取嵌套对象length, 通过管道即可.

如果处理对象是基本属性, 则length返回其字符个数. 如jq '.[0].name|length' json.txt , 结果为4.

如果处理对象是json对象, 则length返回其属性个数. 如jq '.[0].address|length' json.txt, 返回2.

如果处理对象是数组, 则length返回数组的长度. 如jq '.[0].arrayBrowser|length' json.txt , 得到2.

删除某属性

命令格式: jq del(属性表达式) , 一般结合管道使用

该属性可以是基本属性, 或json对象, 或数组

运行 jq '.[0]|del(.address)|del(.arrayBrowser)' json.txt , 得到结果:

{
  "name": "脚本之家",
  "url": "//www.jb51.net"
}

设置元素值

命令格式: jq 属性表达式=新的值' , 一般结合管道使用

新的值可以是基本属性, json对象, 数组.(双引号不能省略)

运行 jq '.[0]|.name="myTool"' json.txt, 得到结果:

{
  "name": "jb51",
  "url": "//www.jb51.net",
  "address": {
    "city": "厦门",
    "country": "中国"
  },
  "arrayBrowser": [
    {
      "name": "Google",
      "url": "http://www.google.com"
    },
    {
      "name": "Baidu",
      "url": "http://www.baidu.com"
    }
  ]
}

增加属性

命令格式: jq 属性表达式+{新的节点} , 一般结合管道使用

其中属性表达式的结果必须为对象

新的节点只能是基本属性, 不能是对象, 数组.

运行jq '.[0].address+{version:"1.0"}' json.txt, 得到结果:

{
  "city": "厦门",
  "country": "中国",
  "version": "1.0"
}

判断是否有某属性

jq '.[0]|has("name")' json.txt, 返回结果为true

jq '.[]|.arrayBrowser[]|has("name")' json.txt #判断单个属性

jq '.[]|.arrayBrowser[]|{a:has("sign"),b:has("name")}' json.txt #判断多个属性并组装成JSON对象

四. 示例文件json.txt

[
  {
    "name": "脚本之家",
    "url": "http://jb51.net",
    "address": {
      "city": "厦门",
      "country": "中国"
    },
    "arrayBrowser": [
      {
        "name": "Google",
        "url": "http://www.google.com"
      },
      {
        "name": "Baidu",
        "url": "http://www.baidu.com"
      }
    ]
  },
  {
    "name": "脚本之家",
    "url": "http://jb51.net",
    "address": {
      "city": "大连",
      "country": "中国"
    },
    "arrayBrowser": [
      {
        "name": "360",
        "url": "http://www.so.com"
      },
      {
        "name": "bing",
        "url": "http://www.bing.com"
      }
    ]
  }
]

到此这篇关于处理JSON最强命令jq使用详解的文章就介绍到这了,更多相关JSON命令jq使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文