Human-readable filesize with find's printf

10,837

Solution 1

Assuming sane file names, with numfmt from gnu coreutils (8.21 or later):

find . -type f -printf '[%TY-%Tm-%Td]\t%s\t%f\n' | numfmt --field=2 --to=iec-i

You can further format the output via --padding= and --format= options (and with most recent versions even set output precision) e.g:

... |  numfmt --field=2 --to=iec-i --suffix=B --padding=8

or

... |  numfmt --field=2 --to=iec-i  --format='%10.3f'

If you don't mind the permissions & links-count columns, with gnu ls:

ls -gohAt --time-style=+%Y-%m-%d

Solution 2

How about -exec du after your -printf ?

eg:

jon@local$ find . -maxdepth 1 -not -iname "." -printf '[%TY-%Tm-%Td]\t' -exec du -bh {} \;
[2015-04-01]    1.6K    ./main.go
[2015-04-01]    5.2K    ./main_test.go

Solution 3

This will require some adaptation if you want to use it, but the dc utility incorporates a little known - if possibly very useful - feature of handling arbitrary output radices. It looks strange at first.

echo 1024o 1025p 1024p 1023p|dc

 0001 0001
 0001 0000
 1023

But its not too difficult to catch on.

ls -s  file;\
ls -hs file;\
echo 1024o 1048576p|dc

1048576 file
1.0G file
 0001 0000 0000

...and...

dd bs=1kx1k seek=500 of=file <>/dev/null 2>&0;\
ls -s  file;\
ls -hs file;\
echo 1024o 512000p|dc

512000
500M
 0500 0000

I'm partial to dc, but bc can do the same kind of thing, it's just not as straight-forward as I regard it.

Anyway, dc will not help you to handle your find ... -printf script - which I think you'll have to do an -exec at least to get it to work the way you want it to if you don't use numfmt as already suggested. But if you were to adapt to something a little more flexible and fleshed out like that, it could be very useful to you. In any case it can probably more easily do much of the job your hr function does.

Share:
10,837

Related videos on Youtube

Ras Knorr
Author by

Ras Knorr

Updated on September 18, 2022

Comments

  • Ras Knorr
    Ras Knorr over 1 year

    I am writing a simple helper function to show a specific folder in the format I want:

    find . -maxdepth 1 -not -name "." -printf '[%TY-%Tm-%Td]\t%s\t%f\n' | sort -n
    

    However I want to show the filesizes in a nicer format. I found this answer which I used to create a bash function called hr.

    user@host:~$ hr 12345
    12M
    

    I tried using this in the find call as so:

    find . -maxdepth 1 -not -name "." -printf '[%TY-%Tm-%Td]\t'$(hr %s)'\t%f\n' | sort -n
    

    But it still continues to show the full filesize. How should I modify this so it works as expected?

    • Admin
      Admin over 8 years
      At first I'd like to offer you to use -exec stat {} + with desired format instead of -printf
    • Admin
      Admin over 8 years
      @don_crissti I want it ordered by date (which is the first column). This is Ubuntu, but also using it on CentOS
  • AATHITH RAJENDRAN
    AATHITH RAJENDRAN almost 3 years
    how do i sort this?