ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Miller then-chaining 用法详解:用 `then` 串联多个动词替代 Unix 管道

Miller then-chaining 用法详解:用 `then` 串联多个动词替代 Unix 管道 CLI数据分析【免费下载链接】millerMiller is like awk, sed, cut, join, and sort for name-indexed data such as CSV, TSV, and tabular JSON项目地址https://gitcode.com/gh_mirrors/mi/miller点击查看免费下载导读本文聚焦 Miller 的 then-chaining 机制即用then关键字Miller 6.3.0 起亦可将多个动词verb串联在同一条命令中其语义与 Unix 管道等价但更省按键。你将掌握如何逐步检查 then-chain 中间输出、理解NR/FNR在链式处理中的真实语义以及为何记录号不连续并学会用 out-of-stream 变量或cat -n恢复连续编号。全文示例可直接复制运行配套数据位于仓库 docs/src/data 目录。一、什么是 then-chainingMiller 遵循 Unix 哲学支持用管道把数据传入或传出。例如 reference-main-then-chaining.md 中的示例mlr cut --complement -f os_version *.dat | mlr sort -f hostname,uptime但你可以不写管道改用then关键字把多个动词串在同一条命令里mlr cut --complement -f os_version then sort -f hostname,uptime *.dat两者产生完全相同的输出。此外为了对称美观第一个动词前也可以写上then例如mlr then cut ...Miller 会接受这种写法。从 pkg/climain/mlrcli_parse.go 的命令行解析逻辑可以看到第一个动词之后的每个动词必须以then或开头同时注释明确说明第一个动词前可以可选地加上then。如果then后面没有跟着动词解析器会报错mlr: then must have a verb after it.。为什么用 then-chaining性能与简洁reference-main-then-chaining.md.in 给出了两条理由并附有一份性能对比性能then-chaining 避免了每个管道阶段之间的冗余字符串解析与格式化。输入记录只被解析一次在内存中依次流过每个管道阶段最后输出记录只被格式化一次。仓库中记录的对比数据data/big约 0.1 秒量级显示管道方式real 0m2.321s链式方式real 0m2.070s链式在用户态 CPU 时间上省了近一半user 0m4.878svsuser 0m2.738s。文档同时提醒这并不是在所有场景下都一定更快是否采用取决于你的数据量与场景。简洁不需要在每个管道阶段重复输入格式化标志如--csv --fs tab。一条mlr --icsv --ojson put ... then filter ... file.csv就同时指定了输入、输出格式和整个变换链。从源码结构看pkg/transformers/aaa_chain_transformer.go 中的ChainTransformer进一步细化了 pkg/stream/stream.go 的高层模型流处理层面看到的是 record-reader → transformer-chain → record-writer 三个 goroutine而ChainTransformer为链中每个 transformer 再细分出 goroutine并用中间 channel 连接相邻阶段——这正是记录在内存中依次流过各阶段的实现基础。二、如何逐步检查 then-chaining 的中间输出面对一条较长的 then-chain最直接的调试方法是一次加一段先只跑第一步省略第一个then之后的所有内容观察中间输出再逐步把后续动词加回去。1. 查看输入数据questions-about-then-chaining.md.in使用仓库内示例数据 docs/src/data/then-example.csvStatus,Payment_Type,Amount paid,cash,10.00 pending,debit,20.00 paid,cash,50.00 pending,credit,40.00 paid,debit,30.002. 只跑第一步mlr --from data/then-example.csv --c2p count-distinct -f Status,Payment_Type输出Status Payment_Type count paid cash 2 pending debit 1 pending credit 1 paid debit 1注意这里用了--c2pCSV 输入转 pretty-print 输出与count-distinct动词按Status,Payment_Type两列分组计数。3. 加上第二步mlr --from data/then-example.csv --c2p count-distinct -f Status,Payment_Type \ then sort -nr count输出与上一步相同Status Payment_Type count paid cash 2 pending debit 1 pending credit 1 paid debit 1本例count列最大值 2 恰好已在首位排序前后输出一致但足以说明加上then sort -nr count后Status、Payment_Type、count三列成为该动词的输入。4. 关键认知上一阶段的输出即下一阶段的输入文档强调如果继续用then追加动词上一步输出的列此处为Status、Payment_Type、count就是下一步的输入。这使你可以像调试 Unix 管道一样逐段观察数据形态的变化。5. 用管道复现相同结果then-chaining 与 Unix 管道在语义上等价下面的写法得到完全相同的输出mlr --from data/then-example.csv --csv count-distinct -f Status,Payment_Type \ | mlr --c2p sort -nr count这也印证了then-chaining 是管道的一种省按键写法这一核心定位。三、为什么 then 之后 NR 不再连续现象对 docs/src/data/small 执行mlr --from data/small filter $x 0.5 then put $NR NR输出aeks,bpan,i2,x0.758679,y0.522151,NR2 awye,bpan,i5,x0.573288,y0.863624,NR5这里看不到NR1、NR2而是NR2、NR5。原因NR在原始输入记录被读取时就已计算好之后不会动态更新。filter $x 0.5丢弃了原始第 1、3、4 条记录保留下来的记录仍然携带它们进入过滤阶段前各自的原始编号于是出现编号跳变。对比NF 是动态的与NR不同NF当前记录字段数是动态计算的增删字段会即时反映echo x1,y2,z3 | mlr put $nf1 NF; $u 4; $nf2 NF; unset $x,$y,$z; $nf3 NF输出nf13,u4,nf25,nf33可以看到初始 3 个字段nf13增加u4后变为 4 个字段nf25删除x,y,z后nf33。注意示例输出中nf25是原文档自带的结果DKVP 输出中字段计数以解析后的键值对为准它说明NF会随记录内容的增删实时变化——这正是它与静态的NR的本质区别。FNR 同理文档明确说明FNR与NR行为一致都保留原始输入流中的编号而 then-chain 内的filter可能丢弃记录因此编号不再连续。四、恢复连续记录号的两套方案方案 Aout-of-stream 变量OOSV用前缀的 out-of-stream 变量维护计数器跨越记录持久存在mlr --opprint --from data/small put begin{ nr1 0 } nr1 1; $nr1 nr1 \ then filter $x0.5 \ then put begin{ nr2 0 } nr2 1; $nr2 nr2 输出a b i x y nr1 nr2 eks pan 2 0.758679 0.522151 2 1 wye pan 5 0.573288 0.863624 5 2关键点begin{ nr1 0 }在put开始处理前初始化计数器第一个put在过滤前逐条加一得到原始序号nr12,5第二个put在过滤后重新计数得到连续序号nr21,2。这展示了 then-chain 中同一批记录经过不同阶段的两种编号视角。方案 Bcat -n一步到位更简单的做法是直接用cat动词的-n标志它在输出时给每条记录前置字段n从 1 开始计数。该标志定义见 pkg/transformers/cat.goPrepend field n to each record with record-counter starting at 1.mlr filter $x 0.5 then cat -n data/small输出n1,aeks,bpan,i2,x0.758679,y0.522151 n2,awye,bpan,i5,x0.573288,y0.863624注意这里filter在链首cat -n接在其后因此n是对过滤后剩余记录连续编号的。五、总结与参考语义then及 6.3.0 起的别名用于在单条mlr命令中串联动词等价于 Unix 管道但更省按键、可避免重复格式标志。调试逐段追加then后的动词观察中间输出上一阶段输出列即下一阶段输入。记录号NR/FNR是读取原始输入时静态算好的不会因链中filter丢弃记录而重新编号NF则是动态字段计数。补救需要连续编号时用 out-of-stream 变量nr 1或cat -n。相关文档与源码可按需深入本文配套原文档questions-about-then-chaining.md.inthen-chaining 总览含性能对比与别名说明reference-main-then-chaining.md.in命令行解析中then/的处理pkg/climain/mlrcli_parse.go链式变换的内存实现pkg/transformers/aaa_chain_transformer.gocat -n计数标志实现pkg/transformers/cat.go赞分享CLI数据分析【免费下载链接】millerMiller is like awk, sed, cut, join, and sort for name-indexed data such as CSV, TSV, and tabular JSON项目地址https://gitcode.com/gh_mirrors/mi/miller点击查看免费下载相关推荐eslint-plugin-unicorn prefer-then-catch 规则详解用 .then().catch() 替代双参数 .then(…, …)eslint plugin unicorn prefer then catch 规则详解用 .then .catch 替代双参数 .then …, … 本文围Lint代码质量如何用Then库优雅简化Swift初始化then、with、do三大核心方法实战指南如何用Then库优雅简化Swift初始化then、with、do三大核心方法实战指南 Then库是Swift开发中一款轻量级但功能强大的工具它通过提供 thAnt Design Message 的 Promise 接口用 .then() 在消息关闭后串联回调Ant Design Message 的 Promise 接口用 .then 在消息关闭后串联回调 Ant Design 的 message 组件除了提供基础前端UI组件设计系统上一篇pingora调试技巧终极指南日志配置与错误追踪实战下一篇CANN/asc-devkit SIMD右移API创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表