Linux jq命令的使用解读

 更新时间:2025年11月11日 10:35:18   作者:fengyehongWorld  
jq 是一个强大的命令行工具,用于处理 JSON 数据,它可以用来查看、过滤、修改、格式化 JSON 数据,通过使用各种选项和过滤器,可以实现复杂的 JSON 处理任务

一. 简介

jq 是 Linux 中的命令行工具,用于处理 JSON 数据。

你可以把它看作是 JSON 的 sed 或 awk,可以用来查看、过滤、修改、格式化 JSON 数据。

  • GitHub 地址https://github.com/stedolan/jq
  • jq 官方网站https://stedolan.github.io/jq/
option解释
-r输出原始格式,而不是 JSON 编码 ⇒ 去掉字段带的"双引号
-R把输入当作原始字符串处理(Raw Input),而不是默认的 JSON 结构。
-c将内容压缩到一行输出。
-s将输入视为多个 JSON 对象,用于处理多个 JSON 对象的数组。
filter解释
.表示当前对象,用于访问字段或属性。
.fieldName选择指定字段的值。
[]用于遍历数组元素。
select(condition)根据条件选择元素。
map(transform)对数组中的每个元素应用转换操作。
格式转换解释
@csv输出 CSV 格式(数组)
@tsv输出 Tab 分隔格式
@json把值转成 JSON 字符串

二. 选项

2.1.

默认的格式化输出

apluser@FengYeHong-HP:~$ echo -n '{"id":1, "name":"zhangsan", "score":[75, 85, 90]}' | jq .
{
  "id": 1,
  "name": "zhangsan",
  "score": [
    75,
    85,
    90
  ]
}

2.2-c

-c选项将内容压缩到一行输出

apluser@FengYeHong-HP:~$ cat data2.json
{
  "id": 1,
  "name": "zhangsan",
  "score": [
    75,
    85,
    90
  ]
}
apluser@FengYeHong-HP:~$ cat data2.json | jq -c
{"id":1,"name":"zhangsan","score":[75,85,90]}

2.3-r

-r选项可以去掉字段两旁的"

apluser@FengYeHong-HP:~$ echo -n '{"id":1, "name":"zhangsan", "score":[75, 85, 90]}' | \
jq '.name' -r
zhangsan

2.4-R

  • 把输入当作原始字符串处理(Raw Input),而不是默认的 JSON 结构。
  • sed 's/"//g':将csv中的"给替换为空。
  • jq -R '[splits(",")]':将逗号分隔的文本行转成数组。
apluser@FengYeHong-HP:~$ cat data.txt
"id","name","age","score"
"1","zhangsan","17","75"
"2","lisi","16","80"
"3","wangwu","18","85"
"4","zhaoliu","18","90"
apluser@FengYeHong-HP:~$ awk 'NR > 1' data.txt | sed 's/"//g' | jq -R '[splits(",")]'
[
  "1",
  "zhangsan",
  "17",
  "75"
]
[
  "2",
  "lisi",
  "16",
  "80"
]
[
  "3",
  "wangwu",
  "18",
  "85"
]
[
  "4",
  "zhaoliu",
  "18",
  "90"
]

三. 字段提取

3.1 普通字段

提取单个字段

apluser@FengYeHong-HP:~$ echo -n '{"id":1, "name":"zhangsan", "score":[75, 85, 90]}' | \
> jq '.name'
"zhangsan"

提取多个字段

apluser@FengYeHong-HP:~$ echo -n '{"id":1, "name":"zhangsan", "score":[75, 85, 90]}' | \
jq '.id, .name'
1
"zhangsan"

提取嵌套字段

apluser@FengYeHong-HP:~$ cat data3.json
{
  "name": "Alice",
  "age": 26,
  "city": "New York",
  "info": {
    "sub_id": 10,
    "sub_address": "地球",
    "sub_num_list": [100, 200, 300]
  }
}
apluser@FengYeHong-HP:~$ cat data3.json | jq '.info.sub_address'
"地球"
# | 的管道符起到过滤作用
apluser@FengYeHong-HP:~$ cat data3.json | jq '.info | .sub_address'
"地球"

3.2 数组字段

提取数组字段中的指定元素,支持切片提取(类似于python的list语法)

apluser@FengYeHong-HP:~$ cat data3.json | jq '.info.sub_num_list[0]'
100
apluser@FengYeHong-HP:~$ cat data3.json | jq '.info.sub_num_list[1]'
200
apluser@FengYeHong-HP:~$ cat data3.json | jq '.info.sub_num_list[2]'
300
apluser@FengYeHong-HP:~$ cat data3.json | jq '.info.sub_num_list[0:2]'
[
  100,
  200
]

数组字段中的对象属性

apluser@FengYeHong-HP:~$ echo '{"items":[{"item_id":1,"name":"すてきな雑貨","price":2500},{"item_id":2,"name":"格好いい置物","price":4500}]}' | \
jq '.items[].name'
"すてきな雑貨"
"格好いい置物"
apluser@FengYeHong-HP:~$ cat data1.json
[
  {
    "name": "Alice",
    "age": 25,
    "city": "New York"
  },
  {
    "name": "Bob",
    "age": 30,
    "city": "Los Angeles"
  },
  {
    "name": "Charlie",
    "age": 22,
    "city": "Chicago"
  }
]
apluser@FengYeHong-HP:~$
apluser@FengYeHong-HP:~$ cat data1.json | jq '.[] | .age'
25
30
22
apluser@FengYeHong-HP:~$ cat data1.json | jq '.[].age'
25
30
22

数组展开

apluser@FengYeHong-HP:~$ echo -n '[75, 85, 90]' | jq '.[]'
75
85
90

四. 编辑

4.1 字段更新

更新一个字段

apluser@FengYeHong-HP:~$ echo -n '{"name":"Alice","age":25,"city":"New York"}' | jq '.name = "贾飞天"'
{
  "name": "贾飞天",
  "age": 25,
  "city": "New York"
}

更新多个字段

apluser@FengYeHong-HP:~$ echo -n '{"name":"Alice","age":25,"city":"New York"}' | jq '. += {"name":"贾飞天", "age":26}'
{
  "name": "贾飞天",
  "age": 26,
  "city": "New York"
}

4.2 字段追加

追加一个字段

apluser@FengYeHong-HP:~$ echo -n '{"name":"Alice","age":25,"city":"New York"}' | jq '.country = "USA"'
{
  "name": "Alice",
  "age": 25,
  "city": "New York",
  "country": "USA"
}

追加一个字段的同时,修改既存的字段

apluser@FengYeHong-HP:~$ echo -n '{"name":"Alice","age":25,"city":"New York"}' | jq '.country = "USA" | .age = 50'
{
  "name": "Alice",
  "age": 50,
  "city": "New York",
  "country": "USA"
}

4.3 字段删除

删除一个字段

apluser@FengYeHong-HP:~$ echo -n '{"name":"Alice","age":25,"city":"New York"}' | jq 'del(.city)'
{
  "name": "Alice",
  "age": 25
}

4.4 转换为csv格式

apluser@FengYeHong-HP:~$ echo '{"items":[{"item_id":1,"name":"すてきな雑貨","price":2500},{"item_id":2,"name":"格好いい置物","price":4500},{"item_id":3,"name":"ナイスなお皿","price":4500}]}' | \
jq .
{
  "items": [
    {
      "item_id": 1,
      "name": "すてきな雑貨",
      "price": 2500
    },
    {
      "item_id": 2,
      "name": "格好いい置物",
      "price": 4500
    },
    {
      "item_id": 3,
      "name": "ナイスなお皿",
      "price": 4500
    }
  ]
}
apluser@FengYeHong-HP:~$ echo '{"items":[{"item_id":1,"name":"すてきな雑貨","price":2500},{"item_id":2,"name":"格好いい置物","price":4500},{"item_id":3,"name":"ナイスなお皿","price":4500}]}' | \
jq '.items[] | [.item_id, .name, .price] | @csv' -r
1,"すてきな雑貨",2500
2,"格好いい置物",4500
3,"ナイスなお皿",4500

五. 过滤

5.1 字段整合

apluser@FengYeHong-HP:~$ echo '{"items":[{"item_id":1,"name":"すてきな雑貨","price":2500},{"item_id":2,"name":"格好いい置物","price":4500}]}' | \
jq '.items[] | { name: .name, yen: .price }'
{
  "name": "すてきな雑貨",
  "yen": 2500
}
{
  "name": "格好いい置物",
  "yen": 4500
}

5.2 select过滤

一个条件

apluser@FengYeHong-HP:~$ cat data1.json
[
  {
    "name": "Alice",
    "age": 25,
    "city": "New York"
  },
  {
    "name": "Bob",
    "age": 30,
    "city": "Los Angeles"
  },
  {
    "name": "Charlie",
    "age": 22,
    "city": "Chicago"
  }
]
apluser@FengYeHong-HP:~$ cat data1.json | jq '.[] | select(.age >= 25) | .name, .city'
"Alice"
"New York"
"Bob"
"Los Angeles"
apluser@FengYeHong-HP:~$ cat data1.json | jq '.[] | select(.age >= 25) | .name, .city' | paste -d "," - -
"Alice","New York"
"Bob","Los Angeles"

多个条件

apluser@FengYeHong-HP:~$ cat data1.json | jq '.[] | select(.age >= 25 and .age <= 30) | .name, .city' | sort
"Alice"
"Bob"
"Los Angeles"
"New York"

六. 函数

6.1 统计函数

6.1.1 add

apluser@FengYeHong-HP:~$ echo '1 2 3 4' | jq -s 'add'
10
apluser@FengYeHong-HP:~$ seq 4 | jq -s 'add'
10
apluser@FengYeHong-HP:~$ echo '{"items":[{"item_id":1,"name":"すてきな雑貨","price":2500},{"item_id":2,"name":"格好いい置物","price":4500}]}' | \
jq '[.items[].price]'
[
  2500,
  4500
]
apluser@FengYeHong-HP:~$ echo '{"items":[{"item_id":1,"name":"すてきな雑貨","price":2500},{"item_id":2,"name":"格好いい置物","price":4500}]}' | \
jq '[.items[].price] | add'
7000

6.1.2 map

apluser@FengYeHong-HP:~$ echo '{"items":[{"item_id":1,"name":"すてきな雑貨","price":2500},{"item_id":2,"name":"格好いい置物","price":4500}]}' | \
jq '.items | map({ name: .name, yen: .price })'
[
  {
    "name": "すてきな雑貨",
    "yen": 2500
  },
  {
    "name": "格好いい置物",
    "yen": 4500
  }
]
apluser@FengYeHong-HP:~$ seq 4 | jq -s 'map(tostring) | join(",")'
"1,2,3,4"

6.1.3 reduce

apluser@FengYeHong-HP:~$ echo '{"items":[{"item_id":1,"name":"すてきな雑貨","price":2500},{"item_id":2,"name":"格好いい置物","price":4500}]}' | jq '.items[]'
{
  "item_id": 1,
  "name": "すてきな雑貨",
  "price": 2500
}
{
  "item_id": 2,
  "name": "格好いい置物",
  "price": 4500
}
apluser@FengYeHong-HP:~$ echo '{"items":[{"item_id":1,"name":"すてきな雑貨","price":2500},{"item_id":2,"name":"格好いい置物","price":4500}]}' | \
jq 'reduce .items[] as $item (0; . + $item.price)'
7000

6.1.4 unique

apluser@FengYeHong-HP:~$ echo '{"items":[{"item_id":1,"name":"すてきな雑貨","price":2500},{"item_id":2,"name":"格好いい置物","price":4500},{"item_id":3,"name":"ナイスなお皿","price":4500}]}' | \
jq '[.items[].price]'
[
  2500,
  4500,
  4500
]
apluser@FengYeHong-HP:~$ echo '{"items":[{"item_id":1,"name":"すてきな雑貨","price":2500},{"item_id":2,"name":"格好いい置物","price":4500},{"item_id":3,"name":"ナイスなお皿","price":4500}]}' | \
jq '[.items[].price] | unique'
[
  2500,
  4500
]

6.1.5 length

apluser@FengYeHong-HP:~$ echo '{"items":[{"item_id":1,"name":"すてきな雑貨","price":2500},{"item_id":2,"name":"格好いい置物","price":4500},{"item_id":3,"name":"ナイスなお皿","price":4500}]}' | \
jq '.items'
[
  {
    "item_id": 1,
    "name": "すてきな雑貨",
    "price": 2500
  },
  {
    "item_id": 2,
    "name": "格好いい置物",
    "price": 4500
  },
  {
    "item_id": 3,
    "name": "ナイスなお皿",
    "price": 4500
  }
]
apluser@FengYeHong-HP:~$ echo '{"items":[{"item_id":1,"name":"すてきな雑貨","price":2500},{"item_id":2,"name":"格好いい置物","price":4500},{"item_id":3,"name":"ナイスなお皿","price":4500}]}' | \
jq '.items | length'
3

6.2 字符串函数

6.2.1 contains

apluser@FengYeHong-HP:~$ echo hello | jq -R 'contains("he")'
true

6.2.2startswith/endswith

apluser@FengYeHong-HP:~$ echo hello | jq -R 'startswith("he")'
true
apluser@FengYeHong-HP:~$ echo hello | jq -R 'endswith("llo")'
true

6.2.3ltrimstr/rtrimstr

apluser@FengYeHong-HP:~$ echo ' hello ' | jq -R 'ltrimstr(" ") | rtrimstr(" ")' -r
hello

6.2.4 大小写转换

apluser@FengYeHong-HP:~$ echo hello | jq -R 'ascii_downcase' -r
hello
apluser@FengYeHong-HP:~$ echo hello | jq -R 'ascii_upcase' -r
HELLO

6.2.5 json对象与json字符串转换

json字符串 ⇒ json对象

apluser@FengYeHong-HP:~$ echo -n '{"id":1,"name":"zhangsan","age":"17","attr":"{\"weight\":56,\"height\":178}"}' | \
jq '.attr = (.attr|fromjson)'
{
  "id": 1,
  "name": "zhangsan",
  "age": "17",
  "attr": {
    "weight": 56,
    "height": 178
  }
}

json对象 ⇒ json字符串

apluser@FengYeHong-HP:~$ echo -n '{"id":1,"name":"zhangsan","age":"17","attr":{"weight":56,"height":178}}' | \
jq '.attr = (.attr|tojson)'
{
  "id": 1,
  "name": "zhangsan",
  "age": "17",
  "attr": "{\"weight\":56,\"height\":178}"
}
apluser@FengYeHong-HP:~$ echo -n '{"id":1,"name":"zhangsan","age":"17","attr":{"weight":56,"height":178}}' | \
jq '.attr = (.attr|tojson)' -c
{"id":1,"name":"zhangsan","age":"17","attr":"{\"weight\":56,\"height\":178}"}

6.3 字段

apluser@FengYeHong-HP:~$ cat data3.json
{
  "name": "Alice",
  "age": 26,
  "city": "New York",
  "info": {
    "sub_id": 10,
    "sub_address": "地球",
    "sub_num_list": [100, 200, 300]
  }
}

6.3.1 keys

  • 获取所有key
apluser@FengYeHong-HP:~$ cat data3.json | jq '. | keys'
[
  "age",
  "city",
  "info",
  "name"
]

6.3.2 values

  • 获取所有value
  • jq-1.6.values方法不好用,此处用[.[]]开替代
apluser@FengYeHong-HP:~$ jq --version
jq-1.6
apluser@FengYeHong-HP:~$ cat data3.json | jq '[.[]]'
[
  "Alice",
  26,
  "New York",
  {
    "sub_id": 10,
    "sub_address": "地球",
    "sub_num_list": [
      100,
      200,
      300
    ]
  }
]

6.3.3 to_entries

  • 转换为键值对数组
apluser@FengYeHong-HP:~$ cat data3.json | jq '. | to_entries'
[
  {
    "key": "name",
    "value": "Alice"
  },
  {
    "key": "age",
    "value": 26
  },
  {
    "key": "city",
    "value": "New York"
  },
  {
    "key": "info",
    "value": {
      "sub_id": 10,
      "sub_address": "地球",
      "sub_num_list": [
        100,
        200,
        300
      ]
    }
  }
]

七. 排序

排序之前

apluser@FengYeHong-HP:~$ echo '[{"name": "Tom", "age": 25},{"name": "Jerry", "age": 18},{"name": "Alice", "age": 30}]' | jq
[
  {
    "name": "Tom",
    "age": 25
  },
  {
    "name": "Jerry",
    "age": 18
  },
  {
    "name": "Alice",
    "age": 30
  }
]

按照指定 字段(age) 升序排序

apluser@FengYeHong-HP:~$ echo '[{"name": "Tom", "age": 25},{"name": "Jerry", "age": 18},{"name": "Alice", "age": 30}]' | \
jq 'sort_by(.age)'
[
  {
    "name": "Jerry",
    "age": 18
  },
  {
    "name": "Tom",
    "age": 25
  },
  {
    "name": "Alice",
    "age": 30
  }
]

按照指定 字段(age) 降序排序

apluser@FengYeHong-HP:~$ echo '[{"name": "Tom", "age": 25},{"name": "Jerry", "age": 18},{"name": "Alice", "age": 30}]' | \
jq 'sort_by(.age) | reverse'
[
  {
    "name": "Alice",
    "age": 30
  },
  {
    "name": "Tom",
    "age": 25
  },
  {
    "name": "Jerry",
    "age": 18
  }
]

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

最新评论