5

Basically what I want to do is to make a script that will output all the files and their sizes in the directory which have size more than a threshold value (2.2 GB in my case). I tried using the stat command as below

a=$(stat -c '%s' example.txt)

but this will store the file size in bytes. What I want is to store and display the size in human readable format(MB,GB). I was also thinking to store the output of ls -lah and then trim the result so as to store only name and size but that seemed a tedious task. Is there other anyway to do this apart from storing the result in bytes and then doing arithmetic operations on it.

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
  • 2
    there's the du command, the -h flag will print a human readable version. the -c flag will print a total size of all listed files. – hyph Nov 19 '17 at 13:36
  • What are some examples of the format you’d like? Should it always use the largest unit? Floating point ? To how many digits of precision? – Jeff Schaller Nov 19 '17 at 16:04
  • 1
    Relating: https://unix.stackexchange.com/q/44040/117549 – Jeff Schaller Nov 19 '17 at 16:26

4 Answers4

9

Since you're already using GNU tools, see numfmt from GNU coreutils:

$ stat -c %s file
310776
$ stat -c '%s' file | numfmt --to=si
311K
$ stat -c '%s' file | numfmt --to=iec
304K
$ stat -c '%s' file | numfmt --to=iec-i
304Ki
$ stat -c '%s' file | numfmt --to=si --suffix=B
311KB

With ksh93:

$ size=$(stat -c %s file)
$ printf "%#d %#i\n" "$size" "$size"
311k 304Ki

Or if built with the ls builtin (which you can also get as a standalone utility in the ast-open package):

$ type ls
ls is a shell builtin version of /opt/ast/bin/ls
$ ls -Z '%#(size)d %#(size)i' file
311k 304Ki
4

No need for a script, just use du -d 0 -t 2200M -h /some/dir/name/*.

Example. Use du to show all files in /bin greater than 500K:

du -d 0 -t 500K -h /bin/*

Output:

1.1M    /bin/bash
620K    /bin/btrfs
2.0M    /bin/busybox
1.6M    /bin/ksh93
788K    /bin/zsh

sort has a complimentary -h that will sort the above by size:

du -d 0 -t 500K -h /bin/* | sort -h

Output:

620K    /bin/btrfs
788K    /bin/zsh
1.1M    /bin/bash
1.6M    /bin/ksh93
2.0M    /bin/busybox
agc
  • 7,223
  • you need to set -d 1 to get the files and the summary includes directories. – bu5hman Nov 20 '17 at 04:42
  • @bu5hman, -d 1 would include files from the first set of subdirectories, which the OP does not require. If files from all subdirs were required, then removing the -d 0 would be simpler. – agc Nov 20 '17 at 05:24
  • my error. As you had typed the path pathToDir/* then -d 0 works. While I had typed pathToDir/ without the wildcard and this requires -d 1. At least on my system. – bu5hman Nov 20 '17 at 09:47
  • Note that du reports disk usage, not size. You could add --apparent-size for that. But for files of type directory, that would still include the size of all entries in the directory (recursively unless you add the -S option). -S --exclude='/bin/*' in combination with LC_ALL=C would help. It should also be noted that most of those options are GNU extensions. – Stéphane Chazelas Nov 20 '17 at 11:11
3

The kind person HERE presents a solution that should help you:

find . -type f -size +2G -exec ls -sh {} \; 2> /dev/null

will give you the fully qualified path name and size in human readable form, all nicely sorted.

If you want 2.2G then find won't handle the decimal, so you will have to do a bit of math and use (2048 + 205 =) 2253M

find . -type f -size +2253M -exec ls -sh {} \; 2> /dev/null

You can constrain the depth of the search and required size with the parameters of find, (see man find), and use awk to output your columns into a file or array.

Edit: -lh changed to -sh and awk removed as per @Olorin improvement

bu5hman
  • 4,756
  • So going down a unit (G to M) and doing the math looks the better option. Thanks @steeldriver for that. – bu5hman Nov 19 '17 at 16:11
  • Use -sh instead of -lh. -s prints just the size, so you don't need the awk after that. – Olorin Nov 20 '17 at 04:28
0
du -h example.txt|cut -f 1

(-h = human readable)

This is under the assumption that your idea of "human readability" and du's idea of this concept is the same.

user1934428
  • 707
  • 5
  • 15