【免费下载链接】jsongrep
A path query language for JSON, YAML, TOML, and other serialization formats.
jsongrep 是一个用 Rust 编写的命令行工具和库,专门用于在 JSON、YAML、TOML 等文档中快速执行路径查询(path query)。它的查询语言复用了正则表达式的设计思路——把 JSON 文档看作一棵树,用"路径上的正则"描述你想匹配的位置。只需掌握下面 10 个核心运算符,你就能写出不限深度的复杂 JSON 搜索。
为什么 jsongrep 的查询像正则表达式?
JSON 文档本质上是一棵树:对象和数组层层嵌套,边由字段名或数组下标标记。jsongrep 让你用正则式运算符描述"路径集合",而不是像jq那样描述"如何转换数据":
**.name # 在任意深度的嵌套对象中找 "name" users[*].email # 匹配 users 数组里每个元素的 email (error|warn).* # error 或 warn 下的任意一层字段查询会先编译为 NFA(非确定有限自动机),再确定化为 DFA(确定有限自动机)执行,因此搜索速度非常快。相关实现可以看 src/query/nfa.rs、src/query/dfa.rs 和 src/query/parser.rs。
10 个正则路径运算符完整清单
| # | 运算符 | 示例 | 含义 |
|---|---|---|---|
| 1 | 顺序拼接 | foo.bar.baz | 依次经过foo→bar→baz |
| 2 | 字段访问 | foo/"foo bar" | 匹配指定字段(含空格需加引号) |
| 3 | 数组下标 | [0]、[1] | 匹配数组中的特定位置 |
| 4 | 数组切片 | [1:3]、[3:]、[:2] | 匹配一段下标(结束位置不包含) |
| 5 | 数组通配符 | [*] | 匹配数组的所有元素 |
| 6 | 字段通配符 | * | 匹配任意一层字段名 |
| 7 | 选择(并集) | year \| category | 匹配多个字段之一 |
| 8 | 可选 | foo?.bar | foo可有可无 |
| 9 | 重复(Kleene 星) | foo* | 前一步重复零次或多次 |
| 10 | 递归下降 | ** | 匹配零层或多层任意字段 |
所有运算符都可以通过括号任意嵌套分组,比如foo.(bar|baz).qux匹配foo.bar.qux或foo.baz.qux。完整文法定义见 src/query/grammar/query.pest。
1. 顺序拼接:按路径逐层深入
最基础的写法,字段之间用.连接:
jg 'name.first' person.json # 输出 name.first: "John"2. 字段访问:支持带空格的字段名
普通字段直接写名称;字段名含空格等保留字符时用双引号包裹:
jg '"first name".value' data.json3. 数组下标:精确定位
下标从 0 开始,字段后可连续追加多个下标,如items[0][1]:
jg 'hobbies[1]' person.json # hobbies.[1]: # "yoga"4. 数组切片:只取一段数据
写法与 Python 切片一致,结束下标不包含:
[1:3]:第 2 到第 4 个元素[3:]:从第 4 个开始到末尾[:2]:前 2 个元素
5. 数组通配符[*]:展开所有元素
这是最常用的运算符之一,取出数组中每个元素:
echo '{"users": [{"name": "Alice"}, {"name": "Bob"}]}' | jg 'users[*].name' # users.[0].name: # "Alice" # users.[1].name: # "Bob"6. 字段通配符*:任意一层字段
注意*只匹配一层字段,不是递归搜索——这是它和**的关键区别:
jg 'dependencies.*.version' Cargo.toml # 列出所有依赖的版本号7. 选择运算|:一次取多个字段
用|在一层内做"或",省掉多次查询:
jg 'prizes[0].(year|category)' prize.json # prizes.[0].year: # "2025" # prizes.[0].category: # "chemistry"8. 可选运算?:字段可能不存在
foo?表示该步可有可无,适合处理字段可选的结构(如 TOML/YAML 配置):
jg 'database.port?.max_connections' config.yaml9. 重复运算*:某一步重复任意次
后缀*让前一个"步骤"重复零次或多次,比如users*会匹配零个、一个或多个users层。
10. 递归下降**:任意深度搜索
**(即"字段通配符 + Kleene 星")是最强的运算符,匹配任意深度的路径:
jg '**.name' tree.json如果想要在对象和数组中都递归,使用(* | [*])*:
jg '(* | [*])*.foo' data.json # 在任何深度找到所有名为 foo 的字段💡 提示:不想手写
**?CLI 的-F/--fixed-string参数会自动把查询当作字段名做任意深度搜索,例如jg -F firstname prize.json等价于**firstname的语义。
实战组合:写出复杂查询的三个技巧
- 括号改变优先级:
(error|warn).message先分组再拼接;不加括号会被解析错。 - 多文件批量查询:同一个查询只编译一次,可依次作用于多个文件并自动识别格式(JSON/YAML/TOML/JSONL/CBOR/MessagePack):
jg 'services.*.image' staging/docker-compose.yml prod/docker-compose.yml - 配合输出参数:
-r输出原始字符串(类似jq -r)、--count统计匹配数、-l只打印有匹配的文件名,方便管道处理。
完整测试数据可参考 tests/data/simple/simple.json。
性能如何:基准测试一图看懂
jsongrep 使用 Criterion 与 jsonpath-rust、jmespath、jaq、jql 四个主流查询库做了对比基准,测试数据从几 KB 的小样例到 190 MB 的 GeoJSON 文件。下图是 xlarge 规模的端到端(解析 + 编译 + 搜索)耗时小提琴图,jsongrep 各查询类型的分布明显更窄更靠左,意味着更快也更稳定:
基准方法论与源码见 benches/README.md 和 benches/query.rs。
快速上手与延伸阅读
🚀 安装与最小示例:
cargo install jsongrep # 或 brew install jsongrep echo '{"a": {"b": 1}}' | jg 'a.b'想了解更多可以逛这些目录:
- 查询引擎核心:src/query/(AST、解析、NFA/DFA)
- 可运行的查询构建器示例:examples/query_builder.rs
- 解析 + 查询完整流程示例:examples/parse_and_query.rs
- 贡献指南:CONTRIBUTING.md
📌 最后一个小知识:文法中还保留了/regex/语法用于"按模式匹配字段名",但引擎尚未实现执行该语法,目前会报 "Unsupported feature" 错误——规划中,敬请期待。
【免费下载链接】jsongrep
A path query language for JSON, YAML, TOML, and other serialization formats.
相关推荐
PyPTO终极指南:CANN新范式AI加速器高性能算子开发框架完全解析
PyPTO终极指南:CANN新范式AI加速器高性能算子开发框架完全解析 PyPTO 是 CANN 推出的面向 AI 加速器的高性能算子开发框架,采用 PTO(P
编译器人工智能高性能计算CANNAscendHound正则表达式搜索:5个高级查询语法完全指南
Hound正则表达式搜索:5个高级查询语法完全指南 Hound是一款闪电般快速的代码搜索引擎,专门为开发者提供高效的正则表达式搜索功能。这款开源工具基于Go语言
搜索引擎开发者工具后端前端Lertaro搜索语法大全:10个运算符玩转fzf风格模糊搜索
Lertaro搜索语法大全:10个运算符玩转fzf风格模糊搜索 Lertaro 是一款面向 Windows 的高性能本地文件搜索工具,基于 NTFS MFT 即
桌面应用搜索引擎开发工具插件系统CLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考