jsont

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

jsont — JSON Traverse

jsont — JSON Traverse

jsont
is a fast CLI for querying and exploring JSON/JSONL data. It replaces throwaway Python scripts and complex jq pipelines with readable, SQL-like queries and built-in data exploration commands.
jt
is a built-in alias — both commands are identical. All examples below use
jt
for brevity.
jsont
是一个用于查询和探索 JSON/JSONL 数据的快速 CLI。它通过易读的类 SQL 查询和内置数据探索命令,取代临时 Python 脚本与复杂的 jq 流水线。
jt
是内置别名——两个命令完全相同。为简洁起见,以下示例均使用
jt
。

Install

安装

bash
curl -fsSL i.jsont.sh | sh
Or with Go:
bash
go install github.com/okaris/jsont/cmd/jt@latest
bash
curl -fsSL i.jsont.sh | sh
或使用 Go:
bash
go install github.com/okaris/jsont/cmd/jt@latest

Start here — pick the right command first

从这里开始——先选择正确的命令

I want to...CommandNotes
Find something in data
jt file find "text"
Always start here. 20 results, truncated, shows paths.
Understand the structure
jt file schema
Shows fields, types, frequencies.
Filter + display
jt file 'where .x == "y" select .a, .b first 20' --table
Use
first N
on large data.
Display mixed-type fields
select substr(to_string(.field), 0, 150) as preview
Universal pattern — never nulls.
Count per category
jt file 'count by .field'
Append
count
to any query — don't pipe.
Search across files
jt *.jsonl find "text" --show-file
Shows source filename per match.
Export
jt file 'select ...' --csv > out.csv
Also:
--table
,
--json
,
--raw
Two-call pattern for any search task:
  1. jt *.jsonl find "failed" --show-file
    — see what's there, which files, which paths
  2. jt *.jsonl 'where .message.content contains "failed" select substr(to_string(.message.content), 0, 150) as preview, .timestamp sort by .timestamp desc first 30' --table
    — structured view
我想……命令备注
在数据中查找内容
jt file find "text"
始终从这里开始。 返回 20 条截断结果,并显示路径。
了解数据结构
jt file schema
显示字段、类型和出现频率。
过滤并显示
jt file 'where .x == "y" select .a, .b first 20' --table
在大型数据上使用
first N
。
显示混合类型字段
select substr(to_string(.field), 0, 150) as preview
通用模式——不会产生 null。
按类别计数
jt file 'count by .field'
将
count
追加到任意查询末尾——不要使用管道。
跨文件搜索
jt *.jsonl find "text" --show-file
显示每条匹配项的来源文件名。
导出
jt file 'select ...' --csv > out.csv
还支持:
--table
、
--json
、
--raw
。
任何搜索任务都采用两次调用模式:
  1. jt *.jsonl find "failed" --show-file
    ——查看有哪些匹配项、位于哪些文件中以及对应路径
  2. jt *.jsonl 'where .message.content contains "failed" select substr(to_string(.message.content), 0, 150) as preview, .timestamp sort by .timestamp desc first 30' --table
    ——结构化视图

Reference files

参考文件

For detailed behavior beyond this guide, read these as needed:
  • references/large-data-playbook.md
    — Step-by-step for large/many files, anti-patterns, output format cheat sheet.
  • references/query-language.md
    — Full operator precedence, all operators/functions with type behavior, edge cases.
  • references/explore-commands.md
    — Detailed explore command output formats and options.
如需了解本指南之外的详细行为,请按需阅读以下文件:
  • references/large-data-playbook.md
    ——面向大型或大量文件的分步指南、反模式以及输出格式速查表。
  • references/query-language.md
    ——完整的运算符优先级、所有运算符/函数及其类型行为和边缘情况。
  • references/explore-commands.md
    ——详细的探索命令输出格式和选项。

When to use jt

何时使用 jt

Use jt instead of writing Python/Node/jq whenever you need to:
  • Understand what's in a JSON/JSONL file (schema, tree, fields, stats, find)
  • Filter, select, sort, count, or group JSON objects
  • Extract fields from large JSONL log files
  • Search for values across deeply nested structures
  • Get quick stats on numeric/string fields
  • Pretty-print or convert between JSON formats (JSON, JSONL, CSV, table)
jt auto-detects JSON vs JSONL, handles stdin, multiple files, and malformed lines gracefully.
需要执行以下操作时,请使用 jt,而不是编写 Python/Node/jq 代码:
  • 了解 JSON/JSONL 文件中有哪些内容(schema、树、字段、统计信息、查找)
  • 过滤、选择、排序、计数或分组 JSON 对象
  • 从大型 JSONL 日志文件中提取字段
  • 搜索深层嵌套结构中的值
  • 快速获取数值/字符串字段的统计信息
  • 美化打印 JSON 或在 JSON 格式之间转换(JSON、JSONL、CSV、表格)
jt 会自动检测 JSON 与 JSONL,支持 stdin 和多个文件,并能妥善处理格式错误的行。

Minimize tool calls

尽量减少工具调用

The goal is one jt command, useful output, done. Avoid multi-step pipelines or piping jt through jt.
Searching for content: Use
find
first — it's one command, auto-truncates long values, and shows exactly where matches are. Don't start with
where
queries on unknown data.
bash
undefined
目标是使用 一条 jt 命令,获得有用输出并完成任务。避免使用多步骤流水线,也不要将 jt 通过管道连接到另一个 jt。
搜索内容:先使用
find
——只需一条命令,它会自动截断较长的值,并准确显示匹配项所在位置。不要在对数据尚不了解时直接使用
where
查询。
bash
undefined

GOOD: one call, clean truncated output

GOOD: one call, clean truncated output

jt *.jsonl find "failed"
jt *.jsonl find "failed"

ONLY if you need filtered/structured results after seeing what find returned:

ONLY if you need filtered/structured results after seeing what find returned:

jt data.jsonl 'where .error.message contains "failed" select .id, .error.message first 20' --table

**Formatting output**: Use flags, not extra commands:

```bash
jt data.jsonl 'select .id, .status first 10' --table    # readable aligned table
jt data.jsonl 'select .id, .status first 10' --csv      # CSV with headers
jt data.jsonl 'select .email' --raw                      # plain strings, no quotes
jt data.jsonl 'where .error exists first 10' --json      # pretty JSON
jt data.jsonl 'where .error.message contains "failed" select .id, .error.message first 20' --table

**格式化输出**:使用参数标志,而不是执行额外命令:

```bash
jt data.jsonl 'select .id, .status first 10' --table    # readable aligned table
jt data.jsonl 'select .id, .status first 10' --csv      # CSV with headers
jt data.jsonl 'select .email' --raw                      # plain strings, no quotes
jt data.jsonl 'where .error exists first 10' --json      # pretty JSON

Large data playbook

大型数据处理指南

For many files or unfamiliar data: schema → find → targeted query. Each is one tool call.
bash
jt data.jsonl schema                                                        # 1. what fields exist?
jt data.jsonl find "error"                                                  # 2. where does it appear? (20 results, truncated)
jt data.jsonl 'where .error.message contains "timeout" select .id, .error.message first 20' --table  # 3. precise query
Always use
first N
with
where
on large data.
find
is already limited by default.
See
references/large-data-playbook.md
for the full guide — anti-patterns, output format cheat sheet, and common task recipes.

对于大量文件或陌生数据:按 schema → find → 定向查询 的顺序进行。每一步都是一次工具调用。
bash
jt data.jsonl schema                                                        # 1. what fields exist?
jt data.jsonl find "error"                                                  # 2. where does it appear? (20 results, truncated)
jt data.jsonl 'where .error.message contains "timeout" select .id, .error.message first 20' --table  # 3. precise query
在大型数据上使用
where
时,务必加上
first N
。
find
默认已经限制返回数量。
有关完整指南,请参阅
references/large-data-playbook.md
——其中包含反模式、输出格式速查表和常见任务示例。

Explore Commands

探索命令

These commands help you understand unfamiliar data fast. No query language needed.
以下命令无需查询语言,即可帮助你快速理解陌生数据。

Pretty-print (default)

美化打印(默认)

bash
jt data.jsonl                    # pretty-print all objects
jt data.json                     # pretty-print single object or array
cat data.jsonl | jt              # stdin works too
bash
jt data.jsonl                    # pretty-print all objects
jt data.json                     # pretty-print single object or array
cat data.jsonl | jt              # stdin works too

schema — Infer types, frequency, and example values

schema——推断类型、频率和示例值

bash
jt data.jsonl schema
Output shows every field path, its types, how often it appears, and sample values. Use this first when exploring unfamiliar data.
bash
jt data.jsonl schema
输出会显示每个字段路径、字段类型、出现频率和示例值。探索陌生数据时应首先使用此命令。

tree — Structural overview

tree——结构概览

bash
jt data.jsonl tree
Hierarchical view with box-drawing characters. Shows optional fields marked with
?
, array types, and mixed types with
|
.
bash
jt data.jsonl tree
以框线字符显示层次结构。可选字段标记为
?
,同时显示数组类型和混合类型,并用
|
表示。

fields — List all unique dot-paths

fields——列出所有唯一的点路径

bash
jt data.jsonl fields
Flat sorted list, one path per line. Includes nested paths (
.error.message
) and array element paths (
.items[].name
). Useful for piping.
bash
jt data.jsonl fields
输出为扁平排序列表,每行一个路径。包含嵌套路径(
.error.message
)和数组元素路径(
.items[].name
),适合通过管道进一步处理。

find — Full-text search across all values

find——跨所有值进行全文搜索

bash
jt data.jsonl find "timeout"           # case-insensitive, returns up to 20 matches
jt data.jsonl find "timeout" 50        # return up to 50 matches
jt nested.jsonl find "error"           # searches at any nesting depth
Returns object index, dot-path where found, and the matching value. Finds things buried deep in nested structures without knowing the exact path.
bash
jt data.jsonl find "timeout"           # case-insensitive, returns up to 20 matches
jt data.jsonl find "timeout" 50        # return up to 50 matches
jt nested.jsonl find "error"           # searches at any nesting depth
返回对象索引、匹配项所在的点路径和匹配值。即使不知道准确路径,也能找到深层嵌套结构中的内容。

stats — Statistical summary

stats——统计摘要

bash
jt data.jsonl stats
Shows: total objects, distinct schema shapes, unique field count, numeric field stats (min/median/p95/p99/max), string field distributions (unique count, top values), and null/missing percentages.
bash
jt data.jsonl stats
显示:对象总数、不同 schema 形态数量、唯一字段数量、数值字段统计信息(最小值/中位数/p95/p99/最大值)、字符串字段分布(唯一值数量、最高频值)以及 null/缺失字段的百分比。

head / tail / count / sample

head / tail / count / sample

bash
jt data.jsonl head 3             # first 3 objects (default 5)
jt data.jsonl tail 3             # last 3 objects (default 5)
jt data.jsonl count              # total number of objects
jt data.jsonl sample 10          # random sample of 10 objects

bash
jt data.jsonl head 3             # first 3 objects (default 5)
jt data.jsonl tail 3             # last 3 objects (default 5)
jt data.jsonl count              # total number of objects
jt data.jsonl sample 10          # random sample of 10 objects

Query Language

查询语言

Readable, SQL-like syntax. All clauses are optional and composable.
jt <files...> '[select FIELDS] [where CONDITION] [sort by FIELD [asc|desc]] [group by FIELD] [count [by FIELD]] [first N | last N]'
采用易读的类 SQL 语法。所有子句均为可选,并且可以组合使用。
jt <files...> '[select FIELDS] [where CONDITION] [sort by FIELD [asc|desc]] [group by FIELD] [count [by FIELD]] [first N | last N]'

Dot-path expressions

点路径表达式

.field                    — object field access
.field.nested             — nested access
.field[0]                 — array index
.field[0].nested          — field access after array index
.field[0].a[1].b          — chained array index + field access
.field[-1]                — last element (negative index)
.field[2:5]               — array slice
.field[]                  — iterate all array elements
.field[].nested           — nested inside each array element
..field                   — recursive descent (find at any depth)
Missing fields return
null
, never error.
.field                    — object field access
.field.nested             — nested access
.field[0]                 — array index
.field[0].nested          — field access after array index
.field[0].a[1].b          — chained array index + field access
.field[-1]                — last element (negative index)
.field[2:5]               — array slice
.field[]                  — iterate all array elements
.field[].nested           — nested inside each array element
..field                   — recursive descent (find at any depth)
缺失字段会返回
null
,而不会报错。

select — Choose output fields

select——选择输出字段

bash
jt data.jsonl 'select .id, .name, .error.message'
jt data.jsonl '.name'                                    # bare path = implicit select
jt data.jsonl 'select .id, .error.message as err'        # alias
jt data.jsonl 'select .id, .end - .start as duration'    # computed
jt data.jsonl 'select .id, .price * .quantity as total'  # arithmetic
jt data.jsonl 'select .items[0].name'                    # array index + field
jt data.jsonl 'select .message.content[0].type'          # nested array + field
jt data.jsonl 'select "\(.first) \(.last)" as name'      # string template
jt data.jsonl 'select *'                                 # all fields (default)
jt data.jsonl 'select .metadata.*'                       # wildcard
bash
jt data.jsonl 'select .id, .name, .error.message'
jt data.jsonl '.name'                                    # bare path = implicit select
jt data.jsonl 'select .id, .error.message as err'        # alias
jt data.jsonl 'select .id, .end - .start as duration'    # computed
jt data.jsonl 'select .id, .price * .quantity as total'  # arithmetic
jt data.jsonl 'select .items[0].name'                    # array index + field
jt data.jsonl 'select .message.content[0].type'          # nested array + field
jt data.jsonl 'select "\(.first) \(.last)" as name'      # string template
jt data.jsonl 'select *'                                 # all fields (default)
jt data.jsonl 'select .metadata.*'                       # wildcard

where — Filter objects

where——筛选对象

bash
undefined
bash
undefined

Comparison

Comparison

jt data.jsonl 'where .status == "failed"' jt data.jsonl 'where .latency_ms > 1000' jt data.jsonl 'where .age >= 18 and .age <= 65' jt data.jsonl 'where .message.content[0].type == "tool_use"' # array index in where
jt data.jsonl 'where .status == "failed"' jt data.jsonl 'where .latency_ms > 1000' jt data.jsonl 'where .age >= 18 and .age <= 65' jt data.jsonl 'where .message.content[0].type == "tool_use"' # array index in where

String operators

String operators

jt data.jsonl 'where .name contains "error"' jt data.jsonl 'where .id starts with "run_"' jt data.jsonl 'where .file ends with ".json"' jt data.jsonl 'where .msg matches /time.*out/i'
jt data.jsonl 'where .name contains "error"' jt data.jsonl 'where .id starts with "run_"' jt data.jsonl 'where .file ends with ".json"' jt data.jsonl 'where .msg matches /time.*out/i'

Set membership

Set membership

jt data.jsonl 'where .status in ("ok", "pending")'
jt data.jsonl 'where .status in ("ok", "pending")'

Existence and type checks

Existence and type checks

jt data.jsonl 'where .error exists' jt data.jsonl 'where .meta is null' jt data.jsonl 'where .content is array' jt data.jsonl 'where .content is string'
jt data.jsonl 'where .error exists' jt data.jsonl 'where .meta is null' jt data.jsonl 'where .content is array' jt data.jsonl 'where .content is string'

Logical operators

Logical operators

jt data.jsonl 'where .status == "failed" and .latency_ms > 1000' jt data.jsonl 'where .code == 429 or .code == 503' jt data.jsonl 'where not .active' jt data.jsonl 'where (.a > 1 or .b > 1) and .c == true'
jt data.jsonl 'where .status == "failed" and .latency_ms > 1000' jt data.jsonl 'where .code == 429 or .code == 503' jt data.jsonl 'where not .active' jt data.jsonl 'where (.a > 1 or .b > 1) and .c == true'

Recursive descent — search at any depth

Recursive descent — search at any depth

jt data.jsonl 'where ..error contains "timeout"'
jt data.jsonl 'where ..error contains "timeout"'

Array contains (element)

Array contains (element)

jt data.jsonl 'where .tags contains "urgent"'

**All where operators:**
`==`, `!=`, `>`, `<`, `>=`, `<=`, `contains`, `starts with`, `ends with`, `matches /regex/`, `in (values)`, `exists`, `is null`, `is <type>`, `and`, `or`, `not`, `()`
jt data.jsonl 'where .tags contains "urgent"'

**所有 where 运算符:**
`==`、`!=`、`>`、`<`、`>=`、`<=`、`contains`、`starts with`、`ends with`、`matches /regex/`、`in (values)`、`exists`、`is null`、`is <type>`、`and`、`or`、`not`、`()`

sort by

sort by

bash
jt data.jsonl 'sort by .latency_ms'              # ascending (default)
jt data.jsonl 'sort by .latency_ms desc'          # descending
jt data.jsonl 'sort by .status, .latency_ms desc' # multi-field
bash
jt data.jsonl 'sort by .latency_ms'              # ascending (default)
jt data.jsonl 'sort by .latency_ms desc'          # descending
jt data.jsonl 'sort by .status, .latency_ms desc' # multi-field

group by

group by

bash
jt data.jsonl 'group by .status'
bash
jt data.jsonl 'group by .status'

Output: {"key": "ok", "count": 100, "items": [...]}

Output: {"key": "ok", "count": 100, "items": [...]}

jt data.jsonl 'select .model, count(), avg(.latency_ms) group by .model'
undefined
jt data.jsonl 'select .model, count(), avg(.latency_ms) group by .model'
undefined

count / count by

count / count by

bash
jt data.jsonl 'count'                             # total
jt data.jsonl 'where .status == "failed" count'   # filtered count
jt data.jsonl 'count by .model'                   # per unique value
jt data.jsonl 'count by .status sort by count desc'
bash
jt data.jsonl 'count'                             # total
jt data.jsonl 'where .status == "failed" count'   # filtered count
jt data.jsonl 'count by .model'                   # per unique value
jt data.jsonl 'count by .status sort by count desc'

first / last

first / last

bash
jt data.jsonl 'first 10'
jt data.jsonl 'where .error exists first 5'
jt data.jsonl 'last 10'
jt data.jsonl 'sort by .latency_ms desc first 20'
bash
jt data.jsonl 'first 10'
jt data.jsonl 'where .error exists first 5'
jt data.jsonl 'last 10'
jt data.jsonl 'sort by .latency_ms desc first 20'

distinct

distinct

bash
jt data.jsonl 'distinct .status'        # unique values
jt data.jsonl 'distinct .model'
bash
jt data.jsonl 'distinct .status'        # unique values
jt data.jsonl 'distinct .model'

Aggregate functions

聚合函数

Work standalone or with
group by
:
bash
jt data.jsonl 'select count()'
jt data.jsonl 'select avg(.latency_ms)'
jt data.jsonl 'select min(.age), max(.age)'
jt data.jsonl 'select sum(.amount)'
jt data.jsonl 'select .model, count(), avg(.latency_ms) group by .model sort by count() desc'
Functions:
count()
,
sum()
,
avg()
,
min()
,
max()
可独立使用,也可与
group by
配合使用:
bash
jt data.jsonl 'select count()'
jt data.jsonl 'select avg(.latency_ms)'
jt data.jsonl 'select min(.age), max(.age)'
jt data.jsonl 'select sum(.amount)'
jt data.jsonl 'select .model, count(), avg(.latency_ms) group by .model sort by count() desc'
函数:
count()
、
sum()
、
avg()
、
min()
、
max()

Scalar functions

标量函数

bash
jt data.jsonl 'select .name, length(.name) as len'
jt data.jsonl 'where length(.tags) > 3'
jt data.jsonl 'select lower(.email) as email'
jt data.jsonl 'select coalesce(.nickname, .name) as display'
jt data.jsonl 'select type(.content) as content_type'
jt data.jsonl 'where .msg matches /error/i select regex_extract(.msg, /error: (.+)/) as err'
Functions:
length()
,
lower()
,
upper()
,
trim()
,
type()
,
keys()
,
values()
,
abs()
,
floor()
,
ceil()
,
round()
,
sqrt()
,
pow()
,
coalesce()
,
if()
,
split()
,
join()
,
replace()
,
substr()
,
to_number()
,
to_string()
,
regex_extract()
,
regex_extract_all()
bash
jt data.jsonl 'select .name, length(.name) as len'
jt data.jsonl 'where length(.tags) > 3'
jt data.jsonl 'select lower(.email) as email'
jt data.jsonl 'select coalesce(.nickname, .name) as display'
jt data.jsonl 'select type(.content) as content_type'
jt data.jsonl 'where .msg matches /error/i select regex_extract(.msg, /error: (.+)/) as err'
函数:
length()
、
lower()
、
upper()
、
trim()
、
type()
、
keys()
、
values()
、
abs()
、
floor()
、
ceil()
、
round()
、
sqrt()
、
pow()
、
coalesce()
、
if()
、
split()
、
join()
、
replace()
、
substr()
、
to_number()
、
to_string()
、
regex_extract()
、
regex_extract_all()

Arithmetic

算术运算

Works in
select
and
where
:
bash
jt data.jsonl 'select .id, .price * .quantity as total'
jt data.jsonl 'where .end - .start > 1000'
jt data.jsonl 'select .id, round(.score * 100, 2) as pct'
Operators:
+
(also string concat),
-
,
*
,
/
,
%

可用于
select
和
where
:
bash
jt data.jsonl 'select .id, .price * .quantity as total'
jt data.jsonl 'where .end - .start > 1000'
jt data.jsonl 'select .id, round(.score * 100, 2) as pct'
运算符:
+
(也可用于字符串拼接)、
-
、
*
、
/
、
%

Combined Queries — Full Pipeline

组合查询——完整流水线

Clauses compose left to right:
bash
undefined
各子句按从左到右的顺序组合:
bash
undefined

Select + filter + sort + limit

Select + filter + sort + limit

jt logs.jsonl 'select .id, .model, .latency_ms where .status == "failed" sort by .latency_ms desc first 10'
jt logs.jsonl 'select .id, .model, .latency_ms where .status == "failed" sort by .latency_ms desc first 10'

Filter + count

Filter + count

jt logs.jsonl 'where .error exists count'
jt logs.jsonl 'where .error exists count'

Count by + sort

Count by + sort

jt logs.jsonl 'count by .model sort by count desc'
jt logs.jsonl 'count by .model sort by count desc'

Recursive search + select

Recursive search + select

jt logs.jsonl 'where ..error contains "timeout" select .id, .error.message'
jt logs.jsonl 'where ..error contains "timeout" select .id, .error.message'

Group with aggregates

Group with aggregates

jt logs.jsonl 'select .model, count(), avg(.latency_ms) as avg_ms group by .model sort by count() desc'

---
jt logs.jsonl 'select .model, count(), avg(.latency_ms) as avg_ms group by .model sort by count() desc'

---

Output Formats

输出格式

jt auto-detects: pretty JSON in terminal, compact JSONL when piped. Override with flags:
FlagFormat
--json
,
-j
Pretty JSON
--jsonl
Compact JSONL (one per line)
--compact
,
-c
Compact JSON
--table
,
-t
ASCII table with headers
--csv
CSV with header row
--tsv
TSV with header row
--raw
,
-r
Raw strings (no JSON quotes)
--nul
,
-0
Null-delimited
jt 会自动检测输出格式:在终端中输出美化的 JSON,通过管道时输出紧凑的 JSONL。可以使用参数覆盖:
参数格式
--json
、
-j
美化的 JSON
--jsonl
紧凑的 JSONL(每行一条记录)
--compact
、
-c
紧凑的 JSON
--table
、
-t
带标题的 ASCII 表格
--csv
带标题行的 CSV
--tsv
带标题行的 TSV
--raw
、
-r
原始字符串(不带 JSON 引号)
--nul
、
-0
Null 分隔格式

Examples

示例

bash
jt data.jsonl 'select .id, .status, .latency_ms first 5' --table
jt data.jsonl 'select .email' --raw | sort -u
jt data.jsonl 'where .active == true' --csv > export.csv
jt data.jsonl head 3 --json
bash
jt data.jsonl 'select .id, .status, .latency_ms first 5' --table
jt data.jsonl 'select .email' --raw | sort -u
jt data.jsonl 'where .active == true' --csv > export.csv
jt data.jsonl head 3 --json

Other output flags

其他输出参数

bash
--show-file        # prepend source filename to each object
--show-index       # prepend object index
--flatten          # flatten nested objects to dot-path keys
--no-color         # disable color

bash
--show-file        # prepend source filename to each object
--show-index       # prepend object index
--flatten          # flatten nested objects to dot-path keys
--no-color         # disable color

Input

输入

  • Auto-detect:
    .json
    (single object or array) vs
    .jsonl
    (newline-delimited)
  • JSON arrays unwrapped:
    [{...}, {...}]
    treated as rows automatically
  • Multiple files:
    jt *.jsonl 'query'
    — union of all files
  • Stdin:
    cat data.jsonl | jt 'query'
    or
    cat data.jsonl | jt - 'query'
    or
    curl api | jt schema
  • Malformed lines: skipped by default.
    --strict
    to error.
    --silent
    to suppress warnings.

  • 自动检测:自动区分
    .json
    (单个对象或数组)与
    .jsonl
    (换行分隔格式)
  • 自动展开 JSON 数组:
    [{...}, {...}]
    会自动作为多行记录处理
  • 多个文件:
    jt *.jsonl 'query'
    ——合并处理所有文件
  • Stdin:
    cat data.jsonl | jt 'query'
    、
    cat data.jsonl | jt - 'query'
    或
    curl api | jt schema
  • 格式错误的行:默认跳过。使用
    --strict
    可返回错误,使用
    --silent
    可隐藏警告。

Handling mixed-type fields

处理混合类型字段

Real-world JSON often has fields that are sometimes a string, sometimes an array (e.g.,
.message.content
). jt handles this:
  • contains
    works on both strings (substring) and arrays (element match)
  • substr()
    ,
    lower()
    ,
    replace()
    ,
    to_string()
    auto-coerce non-strings to JSON — they never return null on wrong types
  • Use
    type(.field)
    to check:
    where .content is string
    or
    where .content is array
bash
undefined
真实世界中的 JSON 字段有时是字符串,有时是数组(例如
.message.content
)。jt 可以处理这些情况:
  • contains
    同时适用于字符串(子字符串匹配)和数组(元素匹配)
  • substr()
    、
    lower()
    、
    replace()
    、
    to_string()
    会自动将非字符串强制转换为 JSON——类型错误时不会返回 null
  • 使用
    type(.field)
    检查类型:
    where .content is string
    或
    where .content is array
bash
undefined

Filter works regardless of content type (string or array)

Filter works regardless of content type (string or array)

jt data.jsonl 'where .message.content contains "error" first 10'
jt data.jsonl 'where .message.content contains "error" first 10'

Display mixed content as truncated string — always works

Display mixed content as truncated string — always works

jt data.jsonl 'where .message.content contains "failed" select substr(to_string(.message.content), 0, 150) as preview, .timestamp sort by .timestamp desc first 30' --table

This pattern — `substr(to_string(.field), 0, N) as name` — is the universal way to display any field as a truncated readable string in table output, regardless of its type.

---
jt data.jsonl 'where .message.content contains "failed" select substr(to_string(.message.content), 0, 150) as preview, .timestamp sort by .timestamp desc first 30' --table

模式 `substr(to_string(.field), 0, N) as name` 是一种通用方式,无论字段是什么类型,都能以截断后的可读字符串形式显示在表格输出中。

---

Complex Query Examples

复杂查询示例

These are real-world one-liners. Use them as templates.
以下都是真实场景中的单行命令,可作为查询模板使用。

Search conversation logs (Claude Code JSONL)

搜索对话日志(Claude Code JSONL)

bash
undefined
bash
undefined

Find user messages containing a term, show truncated preview

Find user messages containing a term, show truncated preview

jt *.jsonl 'where .type == "user" and .message.content contains "error" select substr(replace(to_string(.message.content), "\n", " "), 0, 150) as msg, .timestamp sort by .timestamp desc first 30' --table
jt *.jsonl 'where .type == "user" and .message.content contains "error" select substr(replace(to_string(.message.content), "\n", " "), 0, 150) as msg, .timestamp sort by .timestamp desc first 30' --table

Filter by tool type using array index field access

Filter by tool type using array index field access

jt *.jsonl 'where .message.content[0].type == "tool_use" select .message.content[0].name as tool first 20' --table
jt *.jsonl 'where .message.content[0].type == "tool_use" select .message.content[0].name as tool first 20' --table

Count tool usage by name

Count tool usage by name

jt *.jsonl 'where .message.content[0].type == "tool_use" select .message.content[0].name as tool' --jsonl | jt - 'count by .tool' --table
jt *.jsonl 'where .message.content[0].type == "tool_use" select .message.content[0].name as tool' --jsonl | jt - 'count by .tool' --table

Count messages by type

Count messages by type

jt *.jsonl 'count by .type'
jt *.jsonl 'count by .type'

Find all distinct session IDs with errors

Find all distinct session IDs with errors

jt *.jsonl 'where .message.content contains "failed" distinct .sessionId'
jt *.jsonl 'where .message.content contains "failed" distinct .sessionId'

Search across files, show source file

Search across files, show source file

jt *.jsonl find "timeout" --show-file
undefined
jt *.jsonl find "timeout" --show-file
undefined

API logs / run data

API 日志/运行数据

bash
undefined
bash
undefined

Error rate by model, sorted

Error rate by model, sorted

jt runs.jsonl 'count by .model where .status == "failed" sort by count desc' --table
jt runs.jsonl 'count by .model where .status == "failed" sort by count desc' --table

Slow requests with error details

Slow requests with error details

jt runs.jsonl 'where .latency_ms > 5000 select .id, .model, .latency_ms, coalesce(.error.message, "ok") as err sort by .latency_ms desc first 20' --table
jt runs.jsonl 'where .latency_ms > 5000 select .id, .model, .latency_ms, coalesce(.error.message, "ok") as err sort by .latency_ms desc first 20' --table

P95 latency by model

P95 latency by model

jt runs.jsonl 'select .model, count(), avg(.latency_ms) as avg_ms, max(.latency_ms) as max_ms group by .model sort by count() desc' --table
jt runs.jsonl 'select .model, count(), avg(.latency_ms) as avg_ms, max(.latency_ms) as max_ms group by .model sort by count() desc' --table

Export errors to CSV

Export errors to CSV

jt runs.jsonl 'where .error exists select .id, .error.message, .error.code, .timestamp' --csv > errors.csv
undefined
jt runs.jsonl 'where .error exists select .id, .error.message, .error.code, .timestamp' --csv > errors.csv
undefined

Data inspection

数据检查

bash
undefined
bash
undefined

What types does a field have across objects?

What types does a field have across objects?

jt data.jsonl 'select type(.content) as t distinct .t'
jt data.jsonl 'select type(.content) as t distinct .t'

Find nulls

Find nulls

jt data.jsonl 'where .email is null count'
jt data.jsonl 'where .email is null count'

Objects with unexpected types

Objects with unexpected types

jt data.jsonl 'where .age is string select .id, .age first 10'
undefined
jt data.jsonl 'where .age is string select .id, .age first 10'
undefined