Linux jq 命令使用详解

发布于:2025-05-21 ⋅ 阅读:(16) ⋅ 点赞:(0)

简介

jq 是一个命令行 JSON 处理器,允许解析、过滤、转换和格式化 JSON 数据,提取特定字段或重构 JSON,高效使用 JSON 中的 API 或配置文件。

安装

  • Debian/Ubuntu
sudo apt install jq
  • CentOS/RHEL
sudo yum install jq

或

sudo dnf install jq
  • macOS(Homebrew)
brew install jq

基础语法

jq '<filter>' <file_or_input>

常用选项

  • -r:输出原始字符串(去除 JSON 引号)

  • -c:紧凑输出(不格式化),即去除不必要空格

  • --slurp:将输入合并为单个 JSON 数组

  • --arg:传递外部变量到过滤器

  • --raw-input:将输入视为原始文本(非 JSON

  • -n:不使用输入数据(需手动读取)

  • -S:按键名排序对象字段

  • --tab:使用制表符缩进(美化输出)

  • --arg name value:定义变量,供过滤器使用

  • -M, --monochrome-output:禁用彩色输出

  • -j, --join-output:输出不换行,适合处理多行输出

基本过滤器

  • . : 表示整个输入 JSON

  • .key: 访问对象的字段(例如 .name 提取字段 name 的值)。

  • []: 访问数组元素(例如 .items[0] 提取数组第一个元素)。

  • . | select(condition): 过滤数据,基于条件选择(例如 .[] | select(.age > 30))。

  • . | map(transform): 对数组中的每个元素应用转换(例如 map(.price * 2))。

  • . | length: 获取数组长度或字符串长度。

  • . | keys: 获取对象的键列表。

  • . | sort_by(field): 按指定字段排序数组。

  • . | group_by(field): 按字段分组。

  • . | to_entries: 将对象转换为键值对数组。

  • . | join(","): 将数组元素连接为字符串。

过滤器语法详解

基础操作
  • 格式化输出:
cat data.json | jq '.'  # 美化输出 JSON

输出效果:

{
  "name": "Alice",
  "age": 30,
  "hobbies": ["reading", "hiking"]
}
  • 选择字段:
jq '.[].name' data.json  # 提取数组所有元素的 name 字段
  • 条件过滤:
jq '.[] | select(.age > 25)' data.json  # 过滤年龄大于25的对象
  • 多字段组合:
jq '.[] | {name, city}' data.json  # 组合 name 和 city 字段
  • 新增字段:
jq '.[] | .country = "USA"' data.json  # 添加 country 字段
  • 删除字段:
jq 'del(.[].city)' data.json  # 删除所有元素的 city 字段
  • 数组映射:
jq 'map(.age * 2)' data.json  # 所有年龄翻倍
  • 排序与切片:
jq 'sort_by(.age) | .[:2]' data.json  # 按年龄升序取前2个元素
  • 逻辑运算:and, or, not
jq 'select(.age > 20 and .city == "Beijing")' data.json
  • 内置函数:
jq 'length' data.json        # 数组长度
jq 'keys' data.json          # 对象键名列表
jq 'group_by(.city)' data.json  # 按城市分组
  • 字段访问:
echo '{"user": {"name": "Alice", "age": 30}}' | jq '.user.name'
# 输出:"Alice"
  • 数组索引:
echo '[1, 2, 3]' | jq '.[1]'  # 输出:2
  • 迭代数组:
echo '[{"id":1}, {"id":2}]' | jq '.[].id'  # 输出:1 和 2
  • 多字段选择:
echo '{"name": "Alice", "age": 30}' | jq '{name, age}'
# 输出:{"name": "Alice", "age": 30}
条件与逻辑
  • 条件过滤(if-else):
echo '30' | jq 'if . > 18 then "Adult" else "Child" end'
# 输出:"Adult"
  • 逻辑运算符:
echo '{"age": 20}' | jq 'select(.age >= 18 and .age <= 60)'
# 输出:{"age": 20}
字符串与数学操作
  • 字符串拼接:
echo '{"name": "Alice"}' | jq '"Hello, " + .name'  # 输出:"Hello, Alice"
  • 数学运算:
echo '{"x": 5, "y": 3}' | jq '.x * .y'  # 输出:15
高级操作
  • 递归下降(…):
echo '{"a": {"b": [1, 2]}}' | jq '.. | numbers?'  # 输出:1 和 2
  • 自定义函数:
echo '5' | jq 'def pow(n): . ^ n; pow(3)'  # 输出:125
  • 合并数据(+):
echo '{"a":1} {"b":2}' | jq -s '.[0] + .[1]'  # 输出:{"a":1, "b":2}

用法示例

格式化打印 JSON(彩色、缩进)
cat data.json | jq .

jq '.' fruit.json

curl http://api.open-notify.org/iss-now.json | jq '.'
提取指定字段
cat data.json | jq '.name'
提取嵌套字段
cat data.json | jq '.user.address.city'
从数组里面选择对象
cat data.json | jq '.users[] | select(.age > 30)'
获取对象数组中特定键的所有值
cat data.json | jq '.users[].name'
过滤并输出为新的 JSON 数组
cat data.json | jq '[.users[] | select(.active == true)]'
修改 JSON(添加或更改键)
cat data.json | jq '.users[] += {"role": "guest"}'
将输出格式化为原始字符串(删除引号)
cat data.json | jq -r '.users[].name'
从命令行使用(无需文件)
echo '{"key": "value"}' | jq '.key'
使用管道组合多个过滤器
cat data.json | jq '.users[] | select(.active == true) | .name'
将多个键放入一个新对象中
cat data.json | jq '.users[] | {name, email}'
使用变量
name="John"
cat data.json | jq --arg name "$name" '.users[] | select(.name == $name)'
统计元素
cat data.json | jq '.users | length'
结合 diff 比较 json 文件
diff <(jq -S . file1.json) <(jq -S . file2.json)
合并多个 JSON 对象
echo '{"a":1} {"b":2}' | jq --slurp '.'  

# 输出:{"key": "new_value"}
遍历数组
jq '.items[]'
根据条件选择项目
jq '.users[] | select(.age > 30)'
使用 reduce 进行聚合
jq 'reduce .[] as $item (0; . + $item.value)'
使用walk进行递归遍历
jq 'walk(if type == "string" then ascii_downcase else . end)'   
传递变量
jq --arg var "new_value" '.key = $var' <<< '{"key": "old_value"}' 

# 输出:{"key": "new_value"}
提取 API 响应的特定字段
curl -s https://api.example.com/users | jq '.[].email'
过滤日志中的错误信息
cat logs.json | jq 'select(.level == "ERROR") | .message'
格式化 JSON 文件
jq '.' input.json > formatted.json
重命名字段
echo '{"old_name": "Alice"}' | jq '{new_name: .old_name}'
# 输出:{"new_name": "Alice"}
处理流式 JSON(–stream)

解析大型或流式 JSON 文件:

jq --stream 'select(length==2)' large.json
定义可复用的函数库:
# math.jq
def sqrt: . ^ 0.5;

# 使用
echo '16' | jq 'import "math" as math; math::sqrt'
正则表达式匹配(test)
echo '"alice@example.com"' | jq 'test("@example.com$")'  # 输出:true
调试过滤器(debug)
echo '{"data": [1, 2]}' | jq '.data | debug | .[]'
删除指定字段
jq 'del(.address)' data.json
切片
echo '[1,2,3,4,5,6,7,8,9,10]' | jq '.[6:9]'
返回长度
jq '.fruit | length' fruit.json
批量修改配置文件
jq '.config.timeout = 30' settings.json > tmp.json && mv tmp.json settings.json
生成新的 JSON 对象
jq -n '{"new_field": "value"}'
将用户数据转换为新的结构
jq '.users | map({"full_name": .name, "details": { "age": .age, "location": .city }})' data.json

网站公告

今日签到

点亮在社区的每一天
去签到