登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

Linux numfmt 怎样区分十进制和二进制容量后缀

来源:17golang原创

时间:2026-10-29 07:23:27 210浏览 收藏

GNU numfmt用--from=si按1000进制解释输入,用--from=iec按1024进制解释单字母后缀,用--from=iec-i处理Mi这类双字母二进制后缀。--from=auto把M解释为十进制、Mi解释为二进制;它按后缀约定工作,不会自动判断数据源想表达的单位。

官方地址:https://www.gnu.org/software/coreutils/manual/html_node/numfmt-invocation.html

确定容量清单的输入约定

设想一个归档统计脚本收到两条容量记录:2.5M与2.5Mi。如果来源明确遵循SI和IEC命名,它们本来就代表不同的基础单位数量。问题通常出在某个旧工具把M当作二进制缩写,而后续脚本又按十进制读取。

这个小项目把一行一个容量值转换为不带缩放后缀的数字,供后续统计使用。开始前必须向上游确认:后缀按哪套规则产生、基础单位是什么、是否已经舍入。numfmt是数字缩放工具,不会证明输入是字节;同样的后缀也可能用于其他数量。

比较四种后缀解释

输入模式本例输入解释规则
--from=si2.5M2.5乘1000的平方
--from=iec2.5M2.5乘1024的平方
--from=iec-i2.5Mi双字母Mi对应1024的平方
--from=auto2.5M与2.5Mi分别按十进制和二进制解释

因此,不能只看到了M,就认定它在所有模式下都代表同一个倍率。iec保留了常见的单字母写法,iec-i用带i的写法让意图更明确。auto仅适用于输入后缀遵守其约定的场景;若来源使用M表达二进制,就应明确使用iec,而非交给auto猜测。

numfmt输入模式与缩放基数的静态对应关系
结构说明图:输入模式分组与缩放约定分组说明SI和IEC之间的关联,auto关联后缀规则;这是接口关系图,不是命令运行输出。

建立可复现的命令对照

# 面向GNU Coreutils实现,先查看工具信息。
numfmt --version
# 固定小数点约定;输入数字2.5,比较相同M后缀在两种模式中的解释。
LC_ALL=C numfmt --from=si 2.5M
LC_ALL=C numfmt --from=iec 2.5M
# 双字母Mi明确采用二进制缩放。
LC_ALL=C numfmt --from=iec-i 2.5Mi
# auto按后缀形式判断,不会读取数据源的业务含义。
LC_ALL=C numfmt --from=auto 2.5M 2.5Mi

上述命令供读者复现,未在本文环境运行。根据倍率计算,si的2.5M应得到2500000,iec的2.5M与iec-i的2.5Mi均应得到2621440。auto接收的两个参数则分别对应这两个数值。示例固定LC_ALL=C,避免本地小数点规则干扰这组对照。

先用少量已知值确认输入规则,再接入整个文件。不要为了让某条记录转换成功,就在多种模式之间反复切换直到有结果;这样可能把单位解释错误掩盖成“兼容处理”。来源不明时,应保留原值及来源说明,先解决数据契约。

转换清单并保留失败结果

将下列脚本保存为capacity-convert.sh。它约定M为十进制、Mi为二进制,用标准输入读取清单,不把输入文件名当命令选项。values.candidate与conversion.err是当前调用的候选结果和诊断文件;调用目录应独占,不能由并发任务共用。

#!/bin/sh
# 用法:sh capacity-convert.sh sizes.txt;一行一个容量值。
if [ "$#" -ne 1 ]; then
    printf '%s\n' '请提供容量清单文件' >&2
    exit 2
fi
# 在本次调用独占的目录中保存候选结果,避免覆盖其他任务的文件。
# 输入约定:M表示十进制,Mi表示二进制,基础计量单位由上游确认。
if LC_ALL=C numfmt --from=auto --invalid=abort  values.candidate 2> conversion.err; then
    cat values.candidate || exit 1  # 成功才向后续消费者展示。
else
    result=$?  # 立即保留转换或重定向失败的状态。
    cat conversion.err >&2
    printf '%s\n' '本批转换未完成,候选文件不能用于汇总' >&2
    exit "$result"
fi

选择--invalid=abort,是为了遇到错误便停止。转换失败前可能已有部分数值输出,所以候选文件非空并不表示整批完成;只有成功分支才允许继续消费。非零状态还可能由文件打开失败或其他执行错误引起,应结合诊断处理,不能一律认定容量后缀错误。

原始清单和输入策略应一起保留。后续更改单位解释时,重新从原始数据生成结果;不要从已经格式化、带舍入的展示字符串反向恢复原值。

容量清单转换的输入、候选结果与诊断关系
结构说明图:转换输入分组包含清单、模式和numfmt;结果文件分组说明候选数值、诊断与退出状态的职责,连线不表示执行步骤。

区分展示舍入与原始数值

# 展示格式单独生成,不覆盖用于计算的原始数值。
LC_ALL=C numfmt --to=iec-i 2621440
# 在新建演示目录中准备清单;内容是纯数据,不含注释行。
printf '%s\n' '2.5M' '2.5Mi' '750k' > sizes.txt
# 将上节脚本保存为capacity-convert.sh后,由读者执行。
sh capacity-convert.sh sizes.txt

--from决定如何解释输入,--to决定如何展示输出。输出采用iec-i时会按二进制单位生成易读文本,并可能舍入;这属于展示形式变化,不能代替保留精确基础数值。auto只能用于输入模式,不能用作--to=auto。

本例清单的750k按auto作为SI值解释,其他两条沿用前面的约定。读者在自己的环境中可先比较这三条已知记录,再加入一个非法值观察失败分支;这些是项目复现建议,本文没有执行或生成实测记录。

输出没有B,能直接称为字节数吗?

需要上游确认基础单位。如果原始值明确是字节容量,缩放后的数字才可作为字节数量。numfmt不会补齐业务语义。

所有输入都写M,应选择auto还是iec?

看来源契约。M按十进制产生可用si;M实际表示1024进制时应使用iec。auto对单字母后缀采用SI解释,不能发现上游的特殊约定。

同一条数值格式化再转回来,为什么可能不同?

易读展示可能已经舍入。把展示字符串重新解析,无法保证恢复原始精度,应将计算值与展示值分开保存。

参考:GNU numfmt 官方手册

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>