Is it possible to add a thousands comma separator to the output of the Linux "df" command
df
command gives me good information, and I love to see it in KB unit. But I need a thousands separator (aka: a comma) every 3 digits because the numbers will be always huge.
ex> df
Filesystem 1K-blocks Used Available Use% Mounted on
rootfs 20157076 2982212 16970148 15% /
none 4 0 4 0% /sys/fs/cgroup
/dev/sda2 27206836656 27189604228 17113644 100% /volume1
iwant> df
Filesystem 1K-blocks Used Available Use% Mounted on
rootfs 20,157,076 2,982,212 169,70,148 14.8% /
none 4 0 4 0% /sys/fs/cgroup
/dev/sda2 27,206,836,656 27,189,604,228 17,113,644 100% /volume1
I hate the -h
(human readable) option because it will make everything illogical. Especially unit bytes will be different between every number. I want every number on the same unit.
All I need is a thousands separator… Is there any option for it when using df
?
Solution 1:
You can use awk
to format the numbers with %'d
then use column
to format the table
$ df | LC_ALL=en_US.UTF-8 awk '{
if (NR == 1) { print gensub(/ +/, "\t", "g") } else {
printf("%s\t%'"'"'d\t%'"'"'d\t%'"'"'d\t%d\t%s\n", $1, $2, $3, $4, $5, $6)
} }' | column -t -R 2,3,4,5 -s$'\t'
Filesystem 1K-blocks Used Available Use% Mounted on
dev 1,002,104 0 1,002,104 0 /dev
run 1,011,880 1,060 1,010,820 1 /run
/dev/sda2 36,285,808 17,358,124 17,054,752 51 /
tmpfs 1,011,880 0 1,011,880 0 /dev/shm
tmpfs 1,011,880 0 1,011,880 0 /sys/fs/cgroup
tmpfs 1,011,880 8,300 1,003,580 1 /tmp
/dev/sda1 306,584 264 306,320 1 /boot/efi
tmpfs 202,376 28 202,348 1 /run/user/1000
/dev/sr0 58,122 58,122 0 100 /run/media/mypc/myfolder
By setting the locale with LC_ALL
you can change to any thousand formats available out there. You can also remove the -R
option if you don't want to right-align the numbers or your column
version doesn't have that option (like the default one on Ubuntu)
If you get the function gensub never defined
error then it's because of this bug which can be solved by installing gawk. Alternatively change the delimiter to space instead of tab:
df | LC_ALL=en_US.UTF-8 awk '{
if (NR == 1) { print } else {
printf("%s\t%'"'"'d\t%'"'"'d\t%'"'"'d\t%d\t%s\n", $1, $2, $3, $4, $5, $6)
} }' | column -t
If you want to get the KB value you'll need to divide the corresponding columns
df | LC_ALL=en_US.UTF-8 awk -v K=1024 '{
if (NR == 1) { print gensub(/ +/, "\t", "g") }
else { printf("%s\t%'"'"'d\t%'"'"'d\t%'"'"'d\t%d\t%s\n",
$1, $2/K, $3/K, $4/K, $5, $6) } }
' | column -t -R 2,3,4,5 -s$'\t'
If you want to get a floating-point value just change %d
to %f
df | LC_ALL=en_US.UTF-8 awk -v K=1024 '{
if (NR == 1) { print gensub(/ +/, "\t", "g") }
else { printf("%s\t%'"'"'0.2f\t%'"'"'0.2f\t%'"'"'0.2f\t%d\t%s\n",
$1, $2/K, $3/K, $4/K, $5, $6) } }
' | column -t -R 2,3,4,5 -s$'\t'
Of course you can also align the columns directly from awk
with the field width option like printf "%-10d %10d\n", $1, $2
without needing column
but you'll have to reserve enough space for each column
Solution 2:
Because there is no solution yet, I tried using sed
like below:
df | sed -r ':L;s=\b([0-9]+)([0-9]{3})\b=\1,\2=g;t L'
It works, but result with multi-lines doesn't looks good, because of bad alignment.
But I sadly have to use this line for a while.