jc 本机实测:把 ps/df/ip/ls 输出变成 JSON,jq 一行查询,代价是慢 7 倍
写运维脚本最烦的是解析命令输出:ps aux | awk '$3>0'、ls -l | awk '{print $9}',列一错位就全错。GitHub 上的 kellyjonbrazil/jc 思路很直接:把常见命令的文本输出转成 JSON,再交给 jq 按字段名取值。这篇在本机 Linux 上实际跑了 ps、df、ip route、ls -l 等,和 awk 写法比了正确性和耗时,坑也一并记下。
本机实测 + AI 辅助整理。测量时间:2026-11-01(Asia/Shanghai)。原始输出见文末说明。
本机环境
OS: Linux x86_64
jc: 1.26.2(Python 3.10.22)
jq: 1.7
安装 jc
uv venv v && uv pip install --python v/bin/python jc # 上一篇的 uv,装好不到 1 秒
export PATH=$PWD/v/bin:$PATH
jc --version
也可以 pip install jc、brew install jc,或直接下官方二进制。
实测 1:ps —— 内存占用前三的进程
ps aux | jc --ps | jq -r 'sort_by(-.mem_percent)|.[:3][]|"\(.pid) \(.mem_percent) \(.command[:40])"'
jc 已把 %MEM 转成数字字段 mem_percent,排序不用再 sort -k4 -nr 数第几列。
实测 2:df —— 只看使用率字段
df | jc --df | jq -c '.[]|select(.use_percent>=1)|{filesystem,use_percent,mounted_on}'
# {"filesystem":"/dev/vdb","use_percent":12,"mounted_on":"/"}
use_percent 是整数 12,不是字符串 "12%",比较时不用先去掉百分号。
实测 3:ip route / 地址计算
ip route | jc --ip-route | jq -c '.[]|{ip,via,dev}'
# {"ip":"default","via":"172.30.0.1","dev":"enp0s3"}
# {"ip":"172.17.0.0/16","via":null,"dev":"docker0"}
# {"ip":"172.30.0.0/24","via":null,"dev":"enp0s3"}
jc --ip-address <<< "172.30.0.2/24" | jq -c '{network,broadcast,hosts}'
# {"network":"172.30.0.0","broadcast":"172.30.0.255","hosts":254}
没有网关的路由 via 是 null,脚本里判断很干净。--ip-address 顺手当子网计算器用。
实测 4:ls -l —— 文件名带空格时 awk 翻车
touch "t/a b.txt"
ls -l t | jc --ls | jq -r '.[].filename' # a b.txt
ls -l t | awk 'NR>1{print $9}' # a ← 被空格截断
这是本次最有说服力的一条:按列切分的 awk 天然处理不了带空格的文件名,jc 正确。
找 /usr/bin 下大于 10MB 的文件,两种写法结果一致(都是 3 个:cargo、rustdoc、x86_64-linux-gnu-lto-dump-14):
ls -l /usr/bin | jc --ls | jq '[.[]|select(.size>10000000)]|length' # 3
ls -l /usr/bin | awk '$5>10000000' | wc -l # 3
实测 5:耗时对比
同一件事“统计 CPU 占用 >0 的进程数”,各循环 50 次:
| 写法 | 50 次总耗时 | 单次约 |
|---|---|---|
ps aux | jc --ps | jq ... | 3.387 s | 68 ms |
ps aux | awk 'NR>1 && $3>0' | wc -l | 0.452 s | 9 ms |
jc 慢约 7.5 倍,原因是每次都要启动 Python 解释器(空输入跑一次 jc --ps 就要 0.108 s)。交互用、cron 脚本里无所谓;在紧循环里调几千次就别用了。
彩蛋:magic 语法
jc -p uptime
# {"time":"21:16:20","uptime":"5:30","users":0,"load_1m":8.54, ...}
jc 命令 直接帮你执行并解析,省掉管道。
踩坑记录
--ip-address不是解析ip addr的。我把ip addr管给它直接报could not parse;它解析的是单个 IP/CIDR 字符串。ip route用--ip-route。- dig / ifconfig 本机没装,jc 有
--dig、--ifconfig解析器但前提是命令本身存在;精简镜像里得先装 dnsutils / net-tools(我这台没有 sudo,这两项没测成,不贴编造的结果)。 - 启动开销固定 ~0.1 s,见实测 5。
- 解析失败会提示设
LC_ALL=C:中文 locale 下部分命令输出带中文,jc 可能不认。 uv venv默认不带 pip,所以jc --pip-list要配合uv pip list用(本机解析出 4 个包)。
结论
| 项目 | 结果 |
|---|---|
| 带空格文件名 | jc 正确,awk $9 截断 |
| 字段类型 | 百分比、大小自动转数字,null 显式 |
| 耗时 | 50 次 3.387 s vs awk 0.452 s(≈7.5×慢) |
| 单次启动 | 约 0.108 s |
一句话:jc 换来的是正确性和可读性,代价是 Python 启动时间。写给人看、要长期维护的脚本用 jc + jq;一次性、高频调用的还是 awk。
完整的测量脚本和进阶踩坑表以后会整理上架 Gumroad,先关注专栏「GitHub实测笔记」。
上一篇:uv 本机实测(装 33 个包,pip 9.8 秒 vs uv 0.9 秒)。
下一篇预告:BurntSushi/ripgrep——和 grep 在大目录里比搜索速度。有问题评论区见,看到都会回。