6

I'm working on a little util tool written in bash that gives me some information about a game server on Linux. For that reason I need a possibility to display the size of the file contents.

I'm doing that right now by using this:

du -Lshc *

It works almost perfect! The only flaw is that it displays stuff like this:

21G     backups
22G     server
8.0K    start.sh
151M    world.zip
43G     total

This is fine but I want more digits. Meaning it should look like that:

21.587G     backups
22.124G     server
8.089K      start.sh
151.198M    world.zip
43.436G     total

Is there a possiblility to do that?

I wouldn't mind using a complex command since I use it in a .sh file so I won't type it by hand every time.

0
7
du -Lsbc * | awk '
    function hr(bytes) {
        hum[1024**4]="TiB";
        hum[1024**3]="GiB";
        hum[1024**2]="MiB";
        hum[1024]="kiB";
        for (x = 1024**4; x >= 1024; x /= 1024) {
            if (bytes >= x) {
                return sprintf("%8.3f %s", bytes/x, hum[x]);
            }
        }
        return sprintf("%4d     B", bytes);
    }

    {
        print hr($1) "\t" $2
    }
'

awk-function based on this.

One could probably make the output look a bit nicer by piping it through column or left-padding it with spaces.

Edit: Added the left-padding.

Also, to sort the list: du -Lsbc * | sort -n | awk and then the awk-script.

1
  • This is almost perfect. It only has a little issue if the file size is 0. Then no number is displayed. Another thing is that there are decimal places if the unit is B (Meaning it looks like 108.000B. Which is some kind of akward.) But thank you anyways!
    – BrainStone
    Aug 18 '13 at 13:06
-1

Here is my bash implementation using the code of @n.st

hr() {
    bytes=$1
    hum[1024**4]="TiB";
    hum[1024**3]="GiB";
    hum[1024**2]="MiB";
    hum[1024]="kiB";
    x=0
    for ((x = 1024**4; $x >= 1024; x = ($x/1024) ))
    do
        if [ "$bytes" -ge "$x" ]; then
            $(printf "%8.3f %s" $( echo "$bytes $x" | awk '{printf "%.2f \n", $1/$2}' ) ${hum[$x]});
            return 0;
        fi
    done
    echo $(printf "%4d     B" $bytes);
}

Try

echo $(hr 1024);
echo $(hr 4096);
echo $(hr $((1024*500)) );
echo $(hr $((1024*8000)) );
echo $(hr $((1024*1024*500)) );
echo $(hr $((1024*1024*1024*500)) );
echo $(hr 2127780017);

Output

1.000 kiB
4.000 kiB
500.000 kiB
7.810 MiB
500.000 MiB
500.000 GiB
1.980 GiB
3
  • 2
    The question was about making du output in that format. Not creating a function/script that takes the size as a parameter. You couldn’t even pipe du into it.
    – BrainStone
    Aug 8 '18 at 15:08
  • @BrainStone Yes, who knows maybe someone will need my implementation some day. Aug 8 '18 at 15:14
  • awk is about as portable as bash
    – BrainStone
    Aug 8 '18 at 15:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.