Convert Raw Counts to Readable Units with numfmt
You will finish with a repeatable way to turn values such as byte counts into SI or IEC units, parse readable input back into numbers, and convert selected fields in command output. The examples use GNU coreutils 9.4, installed here as package version 9.4-3ubuntu6.3.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a shell and coreutils. All examples are ordinary, unprivileged commands. They read standard input or literal values and do not change files, services or system configuration.
1. Check the installed command
Start by checking the executable and version. This matters because unit names and defaults are part of the installed implementation, not a property of every command called numfmt:
$ command -v numfmt
/usr/bin/numfmt
$ numfmt --version | head -n 1
numfmt (GNU coreutils) 9.4
$ dpkg-query -W -f='${Package} ${Version}\n' coreutils
coreutils 9.4-3ubuntu6.3
Checkpoint: if the command is missing, stop here and use your normal package-management process to install coreutils. Do not use sudo merely because a conversion command exists; these tests need no elevated privileges.
2. Convert raw numbers to SI or IEC units
Give numbers as arguments when you have a small, known set. --to=si uses powers of 1000, while --to=iec uses powers of 1024 but displays single-letter suffixes. --to=iec-i uses the two-letter suffixes Ki, Mi and so on:
$ numfmt --to=si 1000 1500000
1.0K
1.5M
$ numfmt --to=iec 1024 1048576
1.0K
1.0M
$ numfmt --to=iec-i 1024 1048576
1.0Ki
1.0Mi
The default output has one decimal place. That is a display choice, not extra precision. Use --format when a fixed width or precision is useful. The format must be suitable for one floating-point value, for example %8.1f:
$ numfmt --to=iec --format='%8.1f' 1024
1.0K
Do not confuse SI and IEC when reporting storage or transfer figures. A decimal 1K is 1000; a binary 1K under --to=iec represents 1024.
3. Convert readable input back to numbers
Use --from to accept suffixes. --from=si interprets K as 1000, while --from=iec interprets it as 1024. --from=auto accepts the single-letter and two-letter forms:
$ printf '%s\n' 1K 1Ki 2M | numfmt --from=auto
1000
1024
2000000
$ printf '%s\n' 1K 1M | numfmt --from=iec
1024
1048576
With no --from or --to, the default unit is none. A suffixed input then fails rather than being silently guessed. Make the unit convention explicit in scripts, especially when values come from another tool.
If the input has a fixed unit multiplier already, use --from-unit. For example, a list expressed in kilobytes can be scaled before it is displayed as IEC units:
$ printf '%s\n' 1024 1048576 | numfmt --from-unit=1024 --to=iec-i
1.0Mi
1.0Gi
Checkpoint: check that the producer's unit and the numfmt option agree. A command can succeed while showing a plausible but wrong quantity if you tell it that bytes are kilobytes, or vice versa.
4. Convert columns without damaging labels
When data is separated by whitespace, --field selects the fields to convert. Field ranges follow cut: 2 is one field, 2-4 is an inclusive range, and - means every field. Add --header to pass the first line through unchanged:
$ printf 'name bytes blocks\nalpha 1024 2048\n' | \
numfmt --header --field=2-3 --to=iec
name bytes blocks
alpha 1.0K 2.0K
For comma-separated or tabular data, set the delimiter explicitly. This prevents spaces inside a record from changing which field is selected:
$ printf 'name,bytes,blocks\nalpha,1000,2048\n' | \
numfmt --header --delimiter=, --field=2-3 --to=si
name,bytes,blocks
alpha,1.0K,2.1K
These options preserve the other text and separators. They do not make numfmt a general CSV parser: quoted commas and escaped delimiters are not described by this interface. Use a format-aware parser when the input has CSV quoting rules.
5. Control rounding and alignment
Scaling can lose detail in the displayed value. The default rounding method is from-zero. Choose down, up, towards-zero or nearest when the reporting rule requires it. The option affects scaled output, not the original input:
$ numfmt --to=si --round=down 1550
1.5K
$ numfmt --to=si --round=up 1550
1.6K
$ numfmt --to=si --round=nearest 1550
1.6K
Use --padding for a minimum output width. A positive width right-aligns and a negative width left-aligns. Padding is ignored when the value is already wider than the requested width:
$ numfmt --to=iec --padding=10 1024
1.0K
$ numfmt --to=iec --padding=-10 1024 | od -An -tc
1 . 0 K \n
For stable scripts, prefer --format when you need to specify both width and precision. Do not parse aligned human output as if it were a machine-readable number.
6. Decide what an invalid value should do
The default mode is abort: conversion stops at the first invalid number and exits with status 2. The other modes are useful for reports, but each has a trade-off:
--invalid=faildiagnoses each conversion error and still exits 2.--invalid=warndiagnoses errors and exits 0.--invalid=ignorekeeps invalid text without diagnosing it and exits 0.
$ printf '1000\nbad\n2000\n' | numfmt --to=si --invalid=warn
numfmt: invalid number: bad
1.0K
bad
2.0K
$ printf '1000\nbad\n2000\n' | numfmt --to=si --invalid=fail >/tmp/numfmt-output
$ printf 'exit status: %s\n' "$?"
exit status: 2
The exact diagnostic wording can vary by locale and build. Treat it as a report, not as data to copy into a parser. If bad input must never pass unnoticed, keep the default or use fail and check the exit status. If a later pipeline stage must distinguish clean data from a report containing untouched labels, do not use warn or ignore without an additional validation step.
Done means
- You confirmed the installed GNU coreutils 9.4 version.
- You chose SI, IEC or IEC-i deliberately instead of relying on an implied unit.
- You used
--fromfor suffixed input and checked any fixed multiplier. - You selected data fields and protected headings with
--header. - You chose rounding, formatting and invalid-input behaviour that matches the consumer of the output.
- You ran the workflow without elevated privileges and changed no persistent state.