jq 工具及其常用用法

发布时间 2024-01-04 21:28:49作者: 马昌伟

 

在处理 JSON 数据时,我们经常需要在命令行中进行过滤、查询和编辑的操作。jq 是一个强大的命令行 JSON 处理工具,它可以让我们轻松地对 JSON 数据进行各种操作。本文将简要介绍 jq 的基本概念和常用功能,并提供一些实际的例子。

一、jq 简介

jq 是一个轻量级且灵活的命令行 JSON 处理器。它允许你基于键、值和数组索引来提取、过滤和修改 JSON 数据。jq 主要有以下特性:

  1. 基于流式处理,适用于大型 JSON 数据文件。
  2. 提供了丰富的操作符和函数,与 Unix 的管道(pipe)和 I/O 重定向兼容。
  3. 支持条件过滤、字符串操作、数学运算和自定义函数等高级功能。

二、安装 jq

在大多数 Linux 发行版上,可以通过包管理器轻松安装 jq:

  • 在基于 Debian 的发行版上:
    sudo apt-get install jq
  • 在基于 RHEL 的发行版上:
    sudo yum install jq
  • 在 Arch Linux 上:
    sudo pacman -S jq
  • 在 macOS 上,可以使用 Homebrew 安装:
    brew install jq

三、常用 jq 用法

以下是 jq 的一些常见用法。

1. 读取属性值

要从输入的 JSON 对象中提取属性值,可以使用. 操作符。

举例:有一个名为 sample.json 的文件,内容如下:

{
  "name": "Alice",
  "age": 30,
  "city": "New York"
}

提取名字:

cat sample.json | jq '.name'

输出结果:

"Alice"

2. 过滤数组元素(列表中嵌套字典)

要对数组元素进行过滤,可以使用 [] 操作符。

举例:有一个名为 students.json 的文件,内容如下:

[
  {
    "name": "Alice",
    "age": 30,
    "city": "New York"
  },
  {
    "name": "Bob",
    "age": 25,
    "city": "San Francisco"
  },
  {
    "name": "Charlie",
    "age": 23,
    "city": "Los Angeles"
  }
]

提取所有名字:

cat students.json | jq '.[].name'

输出结果:

"Alice"
"Bob"
"Charlie"

3. 选择特定数组元素

如果要返回具有某些属性的特定元素,则可以使用选择器。例如,要选择年龄超过 25 岁的学生:

cat students.json | jq '.[] | select(.age > 25)'

输出结果:

{
  "name": "Alice",
  "age": 30,
  "city": "New York"
}
[root@mcw02 machangwei]# cat mcwstudents.json | jq '.[]'
{
  "name": "Alice",
  "age": 30,
  "city": "New York"
}
{
  "name": "Bob",
  "age": 25,
  "city": "San Francisco"
}
{
  "name": "Charlie",
  "age": 23,
  "city": "Los Angeles"
}
[root@mcw02 machangwei]# cat mcwstudents.json | jq '.[0]'
{
  "name": "Alice",
  "age": 30,
  "city": "New York"
}
[root@mcw02 machangwei]# cat mcwstudents.json | jq '.[] | select(.age > 25) '
{
  "name": "Alice",
  "age": 30,
  "city": "New York"
}
[root@mcw02 machangwei]# 

 

4. 排序和唯一化数组

可以使用 sort,sort_by() 和 unique 函数对数组进行操作。

例如,对来自 sample-array.json 文件的年龄进行排序和去重:

[30, 20, 25, 30, 25, 20]

排序且去重:

cat sample-array.json | jq 'unique | sort'

输出结果:

[
  20,
  25,
  30
]

[root@mcw02 machangwei]# vim sample-array.json
[root@mcw02 machangwei]# cat sample-array.json
[30, 20, 25, 30, 25, 20]
[root@mcw02 machangwei]# cat sample-array.json| jq 'unique'
[
  20,
  25,
  30
]
[root@mcw02 machangwei]# cat sample-array.json| jq 'unique|sort'
[
  20,
  25,
  30
]
[root@mcw02 machangwei]# 

 

 

5. 修改数据

除了筛选和查询,jq 还支持创建和修改数据。例如,为 students.json 中的每个学生添加 “isActive” 属性:

cat students.json | jq '.[] | {name, age, city, isActive: true}'

输出结果:

{
  "name": "Alice",
  "age": 30,
  "city": "New York",
  "isActive": true
}
{
  "name": "Bob",
  "age": 25,
  "city": "San Francisco",
  "isActive": true
}
{
  "name": "Charlie",
  "age": 23,
  "city": "Los Angeles",
  "isActive": true
}

 

可以添加键值对,但只是显示发生改变,并没有修改掉文件内容

[root@mcw02 machangwei]# cat mcwstudents.json 
[
  {
    "name": "Alice",
    "age": 30,
    "city": "New York"
  },
  {
    "name": "Bob",
    "age": 25,
    "city": "San Francisco"
  },
  {
    "name": "Charlie",
    "age": 23,
    "city": "Los Angeles"
  }
]
[root@mcw02 machangwei]# cat mcwstudents.json |jq '.[]'
{
  "name": "Alice",
  "age": 30,
  "city": "New York"
}
{
  "name": "Bob",
  "age": 25,
  "city": "San Francisco"
}
{
  "name": "Charlie",
  "age": 23,
  "city": "Los Angeles"
}
[root@mcw02 machangwei]# 
[root@mcw02 machangwei]# cat mcwstudents.json |jq '.[]|{name,age,city,isActive:true,shengao:164cm}'
jq: error: syntax error, unexpected IDENT, expecting '}' (Unix shell quoting issues?) at <top-level>, line 1:
.[]|{name,age,city,isActive:true,shengao:164cm}                                            
jq: 1 compile error
[root@mcw02 machangwei]# cat mcwstudents.json |jq '.[]|{name,age,city,isActive:true,shengao:"164cm"}'
{
  "name": "Alice",
  "age": 30,
  "city": "New York",
  "isActive": true,
  "shengao": "164cm"
}
{
  "name": "Bob",
  "age": 25,
  "city": "San Francisco",
  "isActive": true,
  "shengao": "164cm"
}
{
  "name": "Charlie",
  "age": 23,
  "city": "Los Angeles",
  "isActive": true,
  "shengao": "164cm"
}
[root@mcw02 machangwei]# cata mcwstudents.json 
-bash: cata: command not found
[root@mcw02 machangwei]# cat mcwstudents.json 
[
  {
    "name": "Alice",
    "age": 30,
    "city": "New York"
  },
  {
    "name": "Bob",
    "age": 25,
    "city": "San Francisco"
  },
  {
    "name": "Charlie",
    "age": 23,
    "city": "Los Angeles"
  }
]
[root@mcw02 machangwei]# 

 

如下,写上哪个键,就会显示哪个键的。如果不存在的键,需要写上值;如果已经存在的键,不需要写值,默认是文件里的值;如果已经存在的键,又写上值,那么就会替换为修改的值。上面操作不会改变原文件。不过想要这个结果,可以追加到新的文件中。

[root@mcw02 machangwei]# cat mcwstudents.json 
[
  {
    "name": "Alice",
    "age": 30,
    "city": "New York"
  },
  {
    "name": "Bob",
    "age": 25,
    "city": "San Francisco"
  },
  {
    "name": "Charlie",
    "age": 23,
    "city": "Los Angeles"
  }
]
[root@mcw02 machangwei]# 
[root@mcw02 machangwei]# cat mcwstudents.json |jq '.[]|{name,age:18,shengao:"164cm"}'
{
  "name": "Alice",
  "age": 18,
  "shengao": "164cm"
}
{
  "name": "Bob",
  "age": 18,
  "shengao": "164cm"
}
{
  "name": "Charlie",
  "age": 18,
  "shengao": "164cm"
}
[root@mcw02 machangwei]# cat mcwstudents.json 
[
  {
    "name": "Alice",
    "age": 30,
    "city": "New York"
  },
  {
    "name": "Bob",
    "age": 25,
    "city": "San Francisco"
  },
  {
    "name": "Charlie",
    "age": 23,
    "city": "Los Angeles"
  }
]
[root@mcw02 machangwei]# 

 

 

四、总结

jq 是个非常强大的命令行 JSON 处理工具,支持各种数据操作功能,能够帮助你在处理 JSON 数据时更加便捷和高效。本文列举了一些常用的 jq 使用案例,但 jq 的功能远不止于此。更多丰富的功能可以在官方文档(点击查看)中找到。 熟练掌握 jq 有助于提高命令行处理 JSON 数据的能力,为其它处理和分析工具提供更方便的数据源。

 

 

 

来源:https://zhuanlan.zhihu.com/p/661537804