5

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?

4
  • 2
    What you want is not a decimal comma but a thousands separator. I fixed the post for you.
    – slhck
    Commented Oct 22, 2019 at 6:51
  • df internally uses lconv::thousands_sep. How to set it, no idea.
    – Daniel B
    Commented Oct 22, 2019 at 9:20
  • 1
    note that "thousands separator" doesn't mean a comma. It depends on the locale
    – phuclv
    Commented Feb 21, 2020 at 1:59
  • 2
    @DanielB With -h / --human-readable, it is used. In other formats probably not.
    – glglgl
    Commented Feb 26, 2020 at 8:00

3 Answers 3

2

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

2

In Debian and many deriative distros there's numfmt which is part of coreutils that you can use

$ df | LC_ALL=en_US.UTF-8 numfmt --header --field 2-4 --grouping
Filesystem     1K-blocks     Used Available Use% Mounted on
tmpfs            399,676    1,872   397,804   1% /run
/dev/sda2     85,655,680 10,429,248 70,832,348  13% /
tmpfs          1,998,364        0 1,998,364   0% /dev/shm
tmpfs              5,120        4     5,116   1% /run/lock
tmpfs              4,096        0     4,096   0% /sys/fs/cgroup
/dev/sda1        523,248    8,020   515,228   2% /boot/efi
tmpfs            399,672      104   399,568   1% /run/user/1000

Unfortunately although numfmt does try to preserve the columnation, it fails if there are some large variation in the line length after inserting group separators like you can see above. So sometimes you might still need to reformat the table with column

df | LC_ALL=en_US.UTF-8 numfmt --header --field 2-4 --grouping | column -t -R 2,3,4,5

The -R 2,3,4,5 option is for right alignment, but some column versions like the one in Ubuntu (column from util-linux and not from bsdmainutils) don't support it so you need to remove that. Alternatively you can install column from bsdmainutils to get that feature

1

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.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .