Linux man numfmt

numfmt - 读取各种表示形式的数字,并根据要求将其重新格式化。
numfmt 常用于将数字与人类可读格式进行互相转换(例如:1K -> 1024 或者 2097152 -> 2M、2Mi 等)。

版本

$ numfmt --version
numfmt (GNU coreutils) 8.22

语法

numfmt [OPTION]... [NUMBER]...

描述

根据给定的 OPTION(s),重新格式化 NUMBER(s),如果没有提供 NUMBER,则从标准输入中读取。

OPTION

--debug
  将有关可能错误使用的警告信息打印至标准错误(例如:numfmt: no conversion option specified)。

-d, --delimiter=X
  使用 X 作为输入字段分隔符(X 默认值:空格)。
  注意:使用非默认分隔符会导致 --padding 无效。

--field=N
  对输入字段的第 N 个字段进行转换(N 默认值:1)。

--format=FORMAT
  使用 printf 风格的浮点格式化 FORMAT。
  FORMART 格式为:%['][-][N]f。
  FORMART 示例:
  - %'f:等价于 --grouping
  - %10f:等价于 --padding=10
  - %-10f:等价于 --padding=-10

--from=UNIT
  根据单位 UNIT 自动缩放输入数字。
  关于 UNIT 详见下文。

--from-unit=N
  指定输入单位大小为 N(默认值:1)。

--grouping
  根据当前语言环境的分组规则对输出数字中的数字进行分组(例如:千位分隔符,通常为 1,000,000)。
  此选项在 C/POSIX 语言环境中无效。
  
--header[=N]
  对于前 N 行,不进行任何转换,直接打印(N 默认值:1)。

--invalid=MODE
  为无效的输入指定失败模式 MODE(默认值:abort)。
  MODE 可选值:
  - abort:立即中断,以状态 2 退出。
  - fail:为每个转换错误打印警告,以状态 2 退出。
  - warn:为每个转换错误打印警告,以状态 0 退出。
  - ignore:不打印诊断信息,以状态 0 退出。

--padding=N
  通过添加空格将输出数字填充为 N 个字符;
  如果 N 为正数,则数字将右对齐。
  如果 N 为负数,则数字将左对齐。
  默认情况下,(仅当使用默认分隔符时,)数字会根据输入行的宽度自动对齐。

--round=METHOD
  缩放时,使用指定方法 METHOD 进行舍入。
  METHOD 可选值:
  - up:向上舍入
  - down:向下舍入
  - from-zero(默认值):向 0 舍入
  - towards-zero:从 0 舍入
  - nearest:四舍五入

--suffix=SUFFIX
  给输出数字添加后缀 SUFFIX,同时,输入数字如果带有后缀 SUFFIX 也是有效的输入了。

--to=UNIT
  根据单位 UNIT 自动缩放输出数字。
  关于 UNIT 详见下文。

--to-unit=N
  指定输出单位大小为 N(默认值:1)。

--help
  显示帮助信息

--version
  显示版本信息

UNIT 可选值

none
  不执行缩放。
  对于输入数字,不接受后缀,并且数字后的任何尾随字符都会触发错误。
  对于输出数字,将打印完整数字。

si
  根据国际单位制(International System of Units)标准自动缩放数字。
  对于输入数字,接受以下后缀之一。
  对于输出数字,大于 1000 的值将被四舍五入,并使用以下后缀之一打印:
  K => 1000^1 = 10^3 (Kilo)
  M => 1000^2 = 10^6 (Mega)
  G => 1000^3 = 10^9 (Giga)...

iec
  根据国际电工委员会(International Electrotechnical Commission)标准自动缩放数字。
  对于输入数字,接受以下后缀之一。
  对于输出数字,大于 1024 的值将被四舍五入,并使用以下后缀之一打印:
  K => 1024^1 = 2^{10} (Kibi)
  M => 1024^2 = 2^{20} (Mebi)
  G => 1024^3 = 2^{30} (Gibi)...
  注意!iec 使用单个字母的后缀(例如:G),这并不完全符合 IEC 标准,因为 IEC 标准建议使用两个字母的后缀(例如:Gi)。不过,iec 的使用很常见。

iec-i
  根据国际电工委员会(International Electrotechnical Commission)标准自动缩放数字。
  对于输入数字,接受以下后缀之一。
  对于输出数字,大于 1024 的值将被四舍五入,并使用以下后缀之一打印:
  Ki => 1024^1 = 2^{10} (Kibi)
  Mi => 1024^2 = 2^{20} (Mebi)
  Gi => 1024^3 = 2^{30} (Gibi)...
  注意!iec-i 使用两个字母的后缀(例如:Gi),完全符合 IEC 标准,但在实践中并不常见。

auto
  只能与 --from 一起使用。
  使用 auto 时,后缀为 K、M、G、T、P、E、Z、Y 的数字会被解释为 si 值。
  后缀为 Ki、Mi、Gi、Ti、Pi、Ei、Zi、Yi 的数字会被解释为 iec 值。

示例

将单个数字与人类可读格式进行互相转换:

$ numfmt --to=si 500000
500K

$ numfmt --to=iec 500000
489K

$ numfmt --to=iec-i 500000
489Ki

$ numfmt --from=si 1M
1000000

$ numfmt --from=iec 1M
1048576

$ numfmt --from=auto 1M
1000000

$ numfmt --from=auto 1Mi
1048576

从 SI 转换为 IEC 单位(常见于,硬盘广告标为 1TB 容量时,实际可用的容量会更小):

$ numfmt --from=si --to=iec 1T
932G

从输入文件/管道输入转换单个字段(示例仅用于演示目的,ls、df 都支持 --human-reable 选项):

$ ls -log | numfmt --field 3 --header --to=si | head -n4
drwxr-xr-x. 2      4.1K Dec 12  2018 anaconda
drwx------. 2      4.1K Feb 20 13:54 audit
-rw-------  1         0 Sep 16 03:46 boot.log

$ df --block-size=1 | numfmt --field 2 --header --to=iec | head -n4
Filesystem       1B-blocks        Used   Available Use% Mounted on
devtmpfs              909M           0   952958976   0% /dev
tmpfs                 920M           0   963694592   0% /dev/shm
tmpfs                 920M     8118272   955576320   1% /run

使用 --padding、--format 调整输出对齐:

# 右对齐,并使用空格填补为 10 个字符
$ du -s * | numfmt --to=si --padding=10
       164 anaconda
       37K audit
         0 boot.log

# 左对齐,并使用空格填补为 10 个字符
$ du -s * | numfmt --to=si --padding=-10
164        anaconda
37K        audit
0          boot.log

# 右对齐,并使用空格填补为 10 个字符(通过 --format 实现)
$ du -s * | numfmt --to=si --format="%10f"
       164 anaconda
       37K audit
         0 boot.log

# 左对齐,并使用空格填补为 10 个字符(通过 --format 实现)
$ du -s * | numfmt --to=si --format="%-10f"
164        anaconda
37K        audit
0          boot.log

对于支持分组数字的语言环境,使用 --grouping、--format 启用分组(在 POSIX 语言环境中,分组被静默忽略):

$ LC_ALL=C numfmt --from=iec --grouping 2G
2147483648

$ LC_ALL=en_US.utf8 numfmt --from=iec --grouping 2G
2,147,483,648

$ LC_ALL=ta_IN numfmt --from=iec --grouping 2G
2,14,74,83,648

$ LC_ALL=C numfmt --from=iec --format="==%'15f==" 2G
==     2147483648==

$ LC_ALL=en_US.utf8 numfmt --from=iec --format="==%'15f==" 2G
==  2,147,483,648==

$ LC_ALL=en_US.utf8 numfmt --from=iec --format="==%'-15f==" 2G
==2,147,483,648  ==

$ LC_ALL=ta_IN numfmt --from=iec --format="==%'15f==" 2G
== 2,14,74,83,648==

配合管道输入,实现转换为任意格式:

# 从 Gi 转为 M,并移除小数位
$ numfmt --from=iec-i 4Gi | numfmt --to-unit=1048576 --round=down --suffix=M
4096M

$ numfmt --from=iec-i 4.1Gi | numfmt --to-unit=1048576 --round=down --suffix=M
4198M

$ numfmt --from=iec-i 4000Mi | numfmt --to-unit=1048576 --round=down --suffix=M
4000M

参考资料

添加评论

验证码: