Here's a bash-only option, no bc
or any other non-builtins, + decimal format and binary units.
bytesToHuman() {
b=${1:-0}; d=''; s=0; S=(Bytes {K,M,G,T,P,E,Z,Y}iB)
while ((b > 1024)); do
d="$(printf ".%02d" $((b % 1024 * 100 / 1024)))"
b=$((b / 1024))
let s++
done
echo "$b$d ${S[$s]}"
}
Examples:
$ bytesToHuman 123456789
117.73 MiB
$ bytesToHuman 1000000000000 # "1TB of storage"
931.32 GiB # 1TB of storage
$ bytesToHuman
0 Bytes
Should perform well on any version of Bash out there (including MSYSGit's Bash for Windows).