光之远征团跨服战

Linux jq 命令使用详解

简介

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 ''

常用选项

-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

华为荣耀手机第一次充电充多久对电池好?
《铁森林风云》评测:简单易上手剧情向中世纪魔幻CRPG体验


最新发表

友情链接