linux中处理json字符串的jq命令的基本使用
在 shell 脚本中,jq 是一个非常强大的命令行 JSON 处理工具。–arg 参数是 jq 的一个选项,用于在命令行中传递变量到 jq 脚本中。
基本使用
root@ubuntu16041:/work/test# cat my.json
{
"name": "John",
"age": 30,
"father": {
"name": "Tom",
"age": 50
}
}
# 读取name的值
root@ubuntu16041:/work/test# cat my.json |jq .name
"John"
# 读取第二级name的值
root@ubuntu16041:/work/test# jq .father.name my.json
"Tom"
# 读取多个值
(base) {12:13}~/tmp ➭ cat my.json|jq '.name,.age'
"John"
30
# 读取多个值并以json串返回
(base) {12:13}~/tmp ➭ cat my.json|jq '{name,age}'
{
"name": "John",
"age": 30
}
json与jsonl的转换
JSONL 文件(JSON Lines),则是一种每行包含一个独立的 JSON 对象的文本文件格式。 每行都是一个有效的 JSON 对象,和json的"list dict"不一样,jsonl的话没有"list",只有一行行的“dict”,使用换行符分隔。相比于 JSON 文件,JSONL 文件更加轻量,每行为独立的 JSON 对象,没有逗号或其他分隔符。这样的好处是方便一行行读取,而不用像json一样只能一次性把"list"里面的"dict”全部都读出来,节省了内存吧,并且还能增加可读性,普通的json文件打开之后会乱糟糟一团。
- 先创建一个用于测试jsonl文件demon.jsonl
{
"name": "Tom",
"age": 30
}
{
"name": "Alice",
"age": 32
}
- 使用-s '.'将jsonl转换为json
(base) {12:54}~/tmp ➭ cat demo.jsonl |jq -s '.'
[
{
"name": "Tom",
"age": 30
},
{
"name": "Alice",
"age": 32
}
]
- 先创建一个用于测试json文件,demon.json
[
{
"name": "Tom",
"age": 30
},
{
"name": "Alice",
"age": 32
}
]
- 使用.[]将json转换为jsonl
### 转换为jsonl
(base) {12:53}~/tmp ➭ cat demo.json|jq '.[]'
{
"name": "Tom",
"age": 30
}
{
"name": "Alice",
"age": 32
}
修改json变量
- –arg参数进行可以引入外部变量的值。 注意源文件不会被修改
# 注意源文件不会原地修改文件
## 下面命令是把name的值修改为变量指定的值
root@ubuntu16041:/work/test# jq --arg newvalue 'Alice' '.name = $newvalue' my.json
{
"name": "Alice",
"age": 30,
"father": {
"name": "Tom",
"age": 50
}
}
# 这是原文件
root@ubuntu16041:/work/test# cat my.json
{
"name": "John",
"age": 30,
"father": {
"name": "Tom",
"age": 50
}
}
jq的-r参数
- -r表示raw, 输出时不会带"符号
root@ubuntu16041:/work/test# jq '.name' my.json
"John"
root@ubuntu16041:/work/test# jq -r '.name' my.json
John
jq中字段的删除-del()函数
root@ubuntu16041:/work/test# jq < black.json
{
"name": "John",
"age": 30
}
root@ubuntu16041:/work/test# jq 'del(.name)' < black.json
{
"age": 30
}
jq中字段中所有键的获取-keys函数
注意keys默认会排序,如果不需要排序可以用keys_unsorted
# 以数组形式输出
root@ubuntu16041:/work/test# jq -r 'keys' my.json
[
"age",
"father",
"name"
]
# 直接输出key的值
root@ubuntu16041:/work/test# jq -r 'keys[]' my.json
age
father
name
(base) {13:13}~/tmp ➭ jq -r 'keys_unsorted[]' my.json
name
age
father
skills
has函数判断key存在
(base) {13:23}~/tmp ➭ cat my.json|jq
{
"name": "John",
"age": 30,
"father": {
"name": "Tom",
"age": 50
},
"skills": [
{
"name": "football",
"type": "sport"
},
{
"name": "basketball",
"type": "sport"
},
{
"name": "golang",
"type": "computer"
}
]
}
(base) {13:21}~/tmp ➭ cat my.json|jq 'has("age")'
true
(base) {13:21}~/tmp ➭ cat my.json|jq 'has("sex")'
false
(base) {13:23}~/tmp ➭ cat my.json|jq '.skills |map(has("name"))'
[
true,
true,
true
]
jq中的符号
- <符号, 用于将文件内容如作为输入传递给jq
root@ubuntu16041:/work/test# jq < my.json
{
"name": "John",
"age": 30,
"father": {
"name": "Tom",
"age": 50
}
}
- <<<符号, 用于将字符串传递给jq
root@ubuntu16041:/work/test# jq <<< '{"name": "tome","age": 30}'
{
"name": "tome",
"age": 30
}
select过滤字段
#
(base) {12:17}~/tmp ➭ cat my.json|jq 'select(.age >20) | {name}'
{
"name": "John"
}
(base) {12:18}~/tmp ➭ cat my.json|jq 'select(.age >30) | {name}'
列表
先重新创建一个用于测试的json
(base) {12:34}~/tmp ➭ cat my.json|jq
{
"name": "John",
"age": 30,
"father": {
"name": "Tom",
"age": 50
},
"skills": [
{
"name": "football",
"type": "sport"
},
{
"name": "basketball",
"type": "sport"
},
{
"name": "golang",
"type": "computer"
}
]
}
## 获取整个列表
(base) {12:35}~/tmp ➭ cat my.json|jq '.skills'
[
{
"name": "football",
"type": "sport"
},
{
"name": "basketball",
"type": "sport"
},
{
"name": "golang",
"type": "computer"
}
]
## 获取列表第2个元素
(base) {12:36}~/tmp ➭ cat my.json|jq '.skills[1]'
[
{
"name": "football",
"type": "sport"
}
]
## 获取列表第1,第2个元素
(base) {12:36}~/tmp ➭ cat my.json|jq '.skills[0:2]'
[
{
"name": "football",
"type": "sport"
},
{
"name": "basketball",
"type": "sport"
}
]
管道
类似linux的管道一下,可以把输出交给jq再次处理
##
(base) {12:40}~/tmp ➭ cat my.json|jq '.skills[0:2]' |jq '.[] | .name'
"football"
"baskeball"
构建列表
- []符号可以构建一个列表
(base) {13:03}~/tmp ➭ cat my.json|jq '.skills[] | .name'
"football"
"basketball"
"golang"
(base) {13:05}~/tmp ➭ cat my.json|jq '.skills[].name'
"football"
"basketball"
"golang"
## 将结果构建一个列表
(base) {13:06}~/tmp ➭ cat my.json|jq '[.skills[].name]'
[
"football",
"basketball",
"golang"
]
构建对象
- 使用{}符号构建一个对象
(base) {13:08}~/tmp ➭ cat my.json|jq '{name,age,firstskill:.skills[0].name}'
{
"name": "John",
"age": 30,
"firstskill": "football"
}