Convert Raw Counts to Readable Units with numfmt
Log a byte count as "20524362786" and nobody will thank you for it; pipe it through numfmt and it becomes "20.5G" in one command. You will finish with a repeatable way to turn raw numbers into SI or IEC units, parse readable input back into numbers, and convert selected fields inside real command output. 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. Every example here is an ordinary, unprivileged command that reads standard input or literal values, nothing writes to files, services or system configuration.
1. Check the installed command
Check the executable and version first. Unit names and defaults belong to the installed implementation, not to every command that happens to be 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, install coreutils through your normal package-management process. Do not reach for sudo just because a conversion command exists; these tests need no elevated privileges at all.
2. Convert raw numbers to SI or IEC units
Pass numbers as arguments when you have a small, known set:
$ 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
--to=siuses powers of 1000.--to=iecuses powers of 1024 but shows single-letter suffixes.--to=iec-iuses the two-letter suffixesKi,Miand so on.
The default output has one decimal place, that is a display choice, not extra precision. Use --format for a fixed width or precision, with a format suitable for one floating-point value, for example %8.1f:
$ numfmt --to=iec --format='%8.1f' 1024
1.0K
Do not mix up SI and IEC when reporting storage or transfer figures. A decimal 1K is 1000; a binary 1K under --to=iec is 1024, and the gap only grows from there.
3. Convert readable input back to numbers
Use --from to accept suffixes:
$ printf '%s\n' 1K 1Ki 2M | numfmt --from=auto
1000
1024
2000000
$ printf '%s\n' 1K 1M | numfmt --from=iec
1024
1048576
--from=si reads K as 1000, --from=iec reads it as 1024, and --from=auto accepts both the single-letter and two-letter forms. With neither --from nor --to set, the default unit is none, so a suffixed input fails outright instead of being silently guessed. Make the unit convention explicit in scripts, especially when values arrive from another tool.
If the input already has a fixed unit multiplier, use --from-unit. A list expressed in kilobytes, for example, 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 actually agree. A command can succeed while showing a plausible but wrong quantity if you tell it bytes are kilobytes, or the other way round.
4. Convert columns without damaging labels
When data is whitespace-separated, --field selects which fields to convert. Field ranges follow cut: 2 is one field, 2-4 is an inclusive range, - means every field. Add --header to pass the first line through untouched:
$ 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 so a stray space inside a record cannot shift which field gets picked:
$ 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 surrounding text and separators. They do not make numfmt a general CSV parser: quoted commas and escaped delimiters are outside this interface. Reach for a format-aware parser when the input has real CSV quoting rules.
5. Control rounding and alignment
Scaling can lose detail in the displayed value. The default rounding is from-zero; choose down, up, towards-zero or nearest when your reporting rule demands it. It affects only the scaled output, never 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: positive right-aligns, negative left-aligns, and padding is simply ignored once the value is already wider than requested:
$ 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 both width and precision pinned down. Never 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 suit reports, but each trades something away:
--invalid=faildiagnoses each conversion error and still exits 2.--invalid=warndiagnoses errors but 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 varies by locale and build, so treat it as a report, not data to feed 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 needs to tell clean data apart from a report with untouched labels mixed in, do not reach for warn or ignore without an extra validation step.
Done means
- Confirmed the installed GNU coreutils 9.4 version.
- Chose SI, IEC or IEC-i deliberately instead of relying on an implied unit.
- Used
--fromfor suffixed input and checked any fixed multiplier. - Selected data fields and protected headings with
--header. - Chose rounding, formatting and invalid-input behaviour that matches whoever consumes the output.
- Ran the whole workflow unprivileged, with no persistent state changed.