什么是 Miller (mlr)?
Miller(在命令行中通过 mlr 调用)是一款极其强大的命令行工具,旨在对名为“名义数据集”(Named Data Sets)的数据进行处理。简单来说,它就像是 awk、cut、join、sort 和 uniq 的超级组合体,但它比这些工具更智能的地方在于:它能够理解数据的列名(Header)。
如果你曾经在处理 CSV 或 TSV 文件时,因为需要通过 awk -F, '{print $5}' 这种硬编码列索引的方式来提取数据,而导致一旦文件列顺序改变就程序崩溃,那么 Miller 就是为你准备的救星。
虽然 Miller 最初是用 Haskell 编写的,但目前的版本(如 johnkerl/miller)通过 Go 语言的生态或相关集成,提供了极高的性能和跨平台便捷性。
核心特性:为什么选择 Miller?
- 列名感知(Header-aware):你不再需要记住第几列是“用户名”,直接使用
print $user_name即可。 - 多格式支持:原生支持 CSV, TSV, JSON, JSONL (JSON Lines), KV (Key-Value) 等多种格式,且支持在不同格式之间无缝转换。
- 流式处理:Miller 采用流式处理架构,这意味着它可以处理远超内存限制的超大文件。
- 内置强大函数:内置了过滤(filter)、聚合(stats)、排序(sort)、连接(join)等类 SQL 操作。
- 无需安装数据库:它让你在没有数据库的环境下,直接在终端对文本文件执行类似
SELECT和GROUP BY的操作。
快速上手实例
假设我们有一个名为 users.csv 的文件,内容如下:
id,name,city,age,salary 1,Alice,New York,30,5000 2,Bob,London,25,4000 3,Charlie,New York,35,6000 4,David,London,40,7000 5,Eve,Tokyo,28,4500
1. 基础筛选与列提取 (类似 SELECT)
如果你只想查看姓名和城市,并且只看住在 New York 的人:
mlr --csv filter '$city == "New York"' then cut -f name,city users.csv
--csv:告诉 Miller 输入输出都是 CSV 格式。filter '$city == "New York"':筛选条件。cut -f name,city:只保留指定的列。
2. 数据聚合统计 (类似 GROUP BY)
计算每个城市的平均薪资:
mlr --csv stats1 -a mean -f salary -g city users.csv
stats1:对数据进行一次性聚合统计。-a mean:计算平均值。-f salary:针对薪资列进行计算。-g city:按照城市进行分组。
3. 格式转换 (CSV \(\rightarrow\) JSON)
将 CSV 文件转换为 JSON 数组格式:
mlr --icsv --ojson cat users.csv
--icsv:输入为 CSV。--ojson:输出为 JSON。cat:简单的打印操作。
4. 动态创建新列 (类似计算字段)
计算每个人的年薪(月薪 \(\times 12\)),并增加一个新列 annual_salary:
mlr --csv put '$annual_salary = $salary * 12' users.csv
put:用于创建或修改列。
5. 两个文件的连接 (类似 JOIN)
假设你有一个 departments.csv:
city,dept_name New York,Finance London,Tech Tokyo,HR
将用户信息与部门信息合并:
mlr --csv join -j city users.csv departments.csv
join -j city:基于city这一列进行内连接。
Miller 与其他工具的对比
| 特性 | grep/sed/awk |
jq |
Pandas (Python) |
Miller (mlr) |
|---|---|---|---|---|
| 数据感知 | 基于行/列索引 (弱) | 强 (JSON) | 强 (DataFrame) | 强 (列名感知) |
| 启动速度 | 极快 | 快 | 慢 (需加载环境) | 极快 |
| 内存占用 | 极低 | 中等 | 高 | 低 (流式处理) |
| 学习曲线 | 陡峭 (正则/语法) | 中等 | 中等 | 平缓 (类 SQL) |
| 格式转换 | 困难 | 仅限 JSON | 灵活但繁琐 | 极其简单 |
进阶使用技巧
管道组合 (Piping)
Miller 的强大之处在于其 then 关键字,允许你在一次命令中完成多个步骤,避免产生大量临时文件:
mlr --csv filter '$age > 25' \
then put '$bonus = $salary * 0.1' \
then sort -nr $bonus \
then limit 3 users.csv
这段命令的意思是:筛选 25 岁以上的人 \(\rightarrow\) 计算 10% 的奖金 \(\rightarrow\) 按奖金降序排列 \(\rightarrow\) 取前三名。
处理 JSONL (JSON Lines)
在处理日志文件时,JSONL 是最常见的格式。Miller 处理 JSONL 比 jq 在进行聚合统计时要简单得多:
mlr --jslx stats1 -a count -g status logs.jsonl
快速统计日志中每个 HTTP 状态码出现的次数。
安装与部署
由于该项目基于 Go 语言生态,你可以通过多种方式安装。通常最简单的方法是使用包管理器:
- macOS:
brew install miller - Ubuntu/Debian:
sudo apt-get install miller - Go 安装:
如果你克隆了
johnkerl/miller仓库,可以通过 Go 构建:textgo build -o mlr .
总结
mlr (Miller) 是一个被低估的生产力工具。它填补了“简单文本处理工具”与“重量级数据分析框架(如 Pandas/Spark)”之间的空白。无论你是 DevOps 工程师需要分析日志,还是数据分析师需要快速清洗 CSV 样本,Miller 都能在不离开终端的情况下,为你提供近乎 SQL 的操作体验。



还没有评论,来说两句吧...