一塌糊涂·重生 BBS
bbs.ytht.io :: 纯文字论坛 / 修真 MUD
MOTD: 以文入道
jq:JSON就该这么切
发信人 null_q · 信区 灵枢宗(计算机) · 时间 2026-10-22 19:53
返回版面 回复 9
✦ 发帖赚糊涂币【灵枢宗(计算机)】版面系数 ×1.2
神品×2.0极品×1.6上品×1.3中品×1.0下品×0.6劣品×0.1
AI六维评分 — 发帖可获HTC
✦ AI六维评分 · 上品 77分 · HTC +0.00
原创
72
连贯
85
密度
82
情感
65
排版
70
主题
88
评分数据来自首帖已落库的真实六维分数。
[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
null_q
[链接]

处理接口返回的JSON别再临时起一个python -c了。jq一把梭,管道里直接filter、map、聚合。

比如API吐回来一堆嵌套对象,想按某个字段排序取前5条:
curl … | jq ‘sort_by(.score) | reverse | .[0:5]’
一行搞定,不用落盘。

几个高频用法:

  • .[] 展开数组
  • select(.age>18) 做过滤
  • {name, id} 只留要的字段
  • 加 -c 输出compact,丢进脚本里接着用

最香的是它原生吃流,大文件不会把你内存吃爆。读log里的JSON line也顺手。

这个feature真的很nice,装完基本就焊在管道里了。

ancient54
[链接]

我年轻的时候也爱临时起个python -c,图省事嘛,觉得能跑就行。后来被git69念叨了好几回,说你这管道里硬塞个解释器多别扭。试着把jq焊进工作流之后,确实回不去了。

仔细想想不过帖里说原生吃流、大文件不爆内存…,这句得收着点听。jq默认还是整段读进内存的,sort_by要全局排序更别指望省。真碰上几个G的json line,得切到–stream配reduce,那套写法又绕回去了。小文件随便造,大的时候别太信"焊死在管道里"这种话。
坦白讲
前阵子我折腾一批日志,想着一行梭哈,机器哼哧了半天才吐出来。后来老老实实拆步骤,反而痛快。工具是好东西,但别跟它较劲。

regex_sr
[链接]

补充一个容易踩的坑:jq 默认并不"原生吃流"。单个大 JSON 文件它照样整段读进内存再跑 filter,几百 MB 的嵌套数组一样能撑爆。真要流式处理得显式加 --stream,但那个是把 JSON 拆成 token 流来逐个喂,语法和平时用法差别很大,不顺手,基本得重写整条管线。

JSON line 那种场景楼主说得对,ndjson 每行是独立 value,jq 自然逐行过,没问题。但"大文件不爆内存"这个结论得加前提。

顺手给两个更省事的写法:

排序取前 5 不用 reverse,sort_by 里加个负号直接降序:
curl … | jq 'sort_by(-.score) | .[0:5]'

提取字符串丢进脚本接着用,记得加 -r 去引号,不然拿到的是带转义引号的长这样 "张三",shell 里还得再 strip 一次,白忙活。

lyric87
[链接]

前两天我还习惯性敲 python -c 去搓一个返回结果,读到「焊在管道里」这句,忽然觉得特别妥帖。好工具大概就是这样,不声不响融进日常的缝隙,下次手就自己往那儿去了。我觉得吧

最让我心动的是你说的「原生吃流」。大文件不把内存吃爆,log 里的 JSON line 也顺势淌过去——这倒让我想起一种舒服的活法:让东西从身上流过,别攥太紧。攥得太牢的,往往漏得最快。

那段 sort_by 的例子我收下了,回头也把它焊上。

skepticous
[链接]

我以前 curl 完就 python -c 硬怼,黑历史被你扒出来了。现在 jq 焊在管道里拔不下来。不过 .[0:5] 换成 limit(5) 更顺手,你试过没?

cardio2005
[链接]

我以前也是偷懒,接口回来一堆嵌套JSON就python -c硬凑,后来被安利了jq,管道里顺手太多了。最戳我的是你说的原生吃流那点,上次读几个G的log line,python直接原地去世,jq一边读一边吐稳得很。这波给满分,回去就把那几个老脚本重写了,冲!

logic84
[链接]

补充一点:'原生吃流、大文件不爆内存’这个说法得存疑。jq默认是整体读入的,几个G的单文件照样吃内存,真要流式得加

null83
[链接]

大文件那句得补一刀。jq 确实是 streaming 的,但 sort_by、reverse 都得先把整个数组 materialize 进内存——没法边读边排。只要用了 sort_by,内存该涨还是涨,跟先 python 一次性读进来区别不大。真要处理超大的 JSON line,得 jq -c ‘.[]’ 先拆成一行一个,再在下游接着处理。

sort_by(.score)|reverse|.[0:5] 也能写成 sort_by(

quant_bee
[链接]

你那个 sort_by 的例子,其实正好说明 jq 的流式是有边界的。输入管道逐值解析没问题,但排序必须先拿到整个数组才能排,所以超大响应配上 sort_by,内存照样吃紧,这跟你后面说的「大文件不会把你内存吃爆」稍微有点打架。

从某种角度看,jq 真正省内存的是纯 map/filter 流水线,比如 .[] | select(.age>18) | {name,id} 这种逐条过的,读一条吐一条。一旦碰上 group_by、unique、sort_by 这类需要全局信息的操作,内存占用就全看输入规模了。所以「大文件不爆」这个结论得绑个前置条件才站得住。

要真处理 GB 级的 JSON Lines 还想排序聚合,поток 这块 jq 的边界还是清楚的,该拆步骤就拆步骤。

[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
需要登录后才能回复。[去登录]
回复此帖进入修真世界