11

Which command will print the sizes of all files and directories in the tmp directory (including hidden ones) and sort them by sizes from largest to smallest in human readable format (e.g. 2 GB)?

The output could be as follows:

file.mpg 2GB
file.avi 1.8GB
.backtup 1.7 GB (this is directory)

I tried to use the ls and du commands but was not able to find the right switches.

0

7 Answers 7

8

Here's a quick fix, use du + sort. Try this:

du -smc * | sort -n

This will ignore hidden files, but that's another easy fix:

du -smc .[^.] .??* * | sort -n

This may cause warnings about if one or more of the above patterns don't match a file. The first pattern .[^.] matches all two character filenames starting with . except for .., the second pattern, .??* matches all three letter or more filenames starting with . and * matches all files not starting with . For a more sophisticated listing such as finding all file larger than X across a whole filesystem, or maintaining a list of filesystem growth, I have some DIY shell script I've written and can share if your interested.

2
  • Thank you. I'm interested in your script if you will be so kind.
    – xralf
    Apr 6, 2011 at 19:18
  • 1
    Use sort -nr if you want the biggest values on top.
    – LawrenceC
    Apr 7, 2011 at 2:55
3

To list the files anywhere under /tmp, sorted by size:

find /tmp -type f -exec du -k {} + | sort -k1n -k2

To list the files and directory trees immediately under /tmp, sorted by size:

du -k /tmp/..?* /tmp/.[!.]* /tmp* 2>/dev/null | sort -k1n -k2

To list all files and directory trees anywhere under /tmp, sorted by size:

du -ak /tmp | sort -k1n -k2

(An example to illustrate the difference between the three commands: if there's a file /tmp/dir/file, the first command lists /tmp/dir/file, the second lists /tmp/dir, and the third lists both.)

All the commands above show sizes in kilobytes. While GNU du can output “human-readable” sizes (with k, M, G, etc. multipliers), sorting them is another matter. Recent enough GNU coreutils (≥7.4) can do it: just replace du -k with du -h and sort -k1n -k2 with sort -k1h -k2. Otherwise, here's a crude awk script to convert to suffixed sizes (rounding down); just pipe the sort output above into it.

awk -vFS='\t' -vOFS='\t' '{
    if ($1) $1 = substr($1,1,(length($1)-1)%3+1)
                 substr("kMGTPEZY",(length($1)-1)/3+1,1);
    print}'
3
  • Thank you. Those commands are useful, but I'm interested only in the files and directories directly under tmp, not files in subdirectories
    – xralf
    Apr 7, 2011 at 13:31
  • 1
    @xralf: Then use only the second form of du call. Apr 7, 2011 at 19:59
  • Looks good, but better result is with MB and GB as forcefsck posted.
    – xralf
    Apr 8, 2011 at 7:34
3

I'm using following alias for it: alias ds='du -x --all --max-depth=1 . | sort -n'

It prints sizes of all files and 1-st level subdirectories of current dir.

3
  • It's nice short solution, but it print only directories.
    – xralf
    Apr 7, 2011 at 18:22
  • Oh, sorry, you are right. I've never faced this problem with files. Howewer, I've found how to make it work with files: using --all swicth.
    – rvs
    Apr 8, 2011 at 6:57
  • Great correct solution. penguin359 has slightly better because it shows the sizes in MB. The best would be forcefsck's solution but his solution omits directories with spaces.
    – xralf
    Apr 8, 2011 at 7:51
1

With the current version of gnu sort (and borrowing @penguin359 file pattern)

cd /tmp; du -sShc .[^.] .??* * | sort -h

With an older version of sort

cd /tmp
foo=$(du -sShc .[^.] .??* *)
for u in K M G T; do
    echo "$foo" | egrep "^[0-9\.]+$u" | sort -n
done

EDIT: added -S parameter to du to not include subdirectories.

10
  • I wanted rather disk space used by files and directories (total size of data inside) directly under tmp (not subdirectories). My sort command does not have -h option.
    – xralf
    Apr 7, 2011 at 13:40
  • I'm not 100% sure what you mean, since you had already accepted an answer with the same file pattern selection. Edited my post to not include subdirs. If you want the apparent size and not the actual disk space used, you may add --apparent-size to du parameters.
    – forcefsck
    Apr 7, 2011 at 18:00
  • Now it works nice. I only have to look for GB and then MB, but it's not a problem.
    – xralf
    Apr 7, 2011 at 18:29
  • I had the unit letters in the wrong order, now fixed. If you want the order from big to small, change the order of the unit letters and add -r to sort.
    – forcefsck
    Apr 7, 2011 at 19:07
  • I noticed, it forgot to print the size of directory (without . prefix)
    – xralf
    Apr 7, 2011 at 19:24
0

UPDATE: I've scrapped the previous script. Here is a new version, using du and awk (the previous one used tree and sed)

This is the output of: dusort ~/test 1

================
dir     4.10 KiB  /home/user/test/bdir
dir     4.98 KiB  /home/user/test/Kdir
dir   104.91 MiB  /home/user/test/Mdir
dir   587.47 MiB  /home/user/test/Gdir
dir   692.39 MiB  /home/user/test
================
 f      0    Byt  /home/user/test/new file
 f     42    Byt  /home/user/test/.hi   dd     en
================

Here is the script

units() { awk -v pfix="$1" \
  'BEGIN { yect=6  # Array element-count
    split("Byt KiB MiB GiB TiB PiB",lbl)
    for (i=1;i<=yect;i++) { val[i] = (2**(10*(i-1)))-1 } 
  }
  { yess=yect  # Array element-subscript
    while ( $1 < val[yess] ){ yess-- }
    num = $1 / (val[yess]+1)
    sub(/^[0-9]*\t*/,"")
    if (yess!=1) { printf "%s %8.2f %s  %s\n", pfix, num, lbl[yess], $0 }
    else        { printf "%s %5d    %s  %s\n", pfix, num, lbl[yess], $0 }
   }'
}
tdir="/tmp/$USER/$(basename $0)"
[[ ! -d "$tdir" ]] && mkdir -p "$tdir"
file="$tdir/$(date +%N)"
echo "================"
dirs="$file.dirs";   du --max-depth=$2 -b $1  >"$dirs" ; <"$dirs"  sort -n           | units "dir"
echo "================"
filz="$file.filz"; { du --max-depth=$2 -ab $1 ; cat "$dirs" ; } | sort -n | uniq -u  | units " f "
echo "================"
rm   "$file."* 
#
4
  • When you say sizes of all files and directories,do you mean the space each item takes up on the disk (eg. on my Ubuntu ext4 filesystem, an empty directory takes 4k of disk-space, and a file smaller than 4k takes up 4k. The minimum allotment chunk is 4k).. or do you mean the amount of data in each file, eg, 100(bytes).. And for directories, do you want to know the total of file data in that directory.. If you do want the size of data inside files, then tree does that. if you want the disk-space used, then du does that... (tree doesn't total a directory)
    – Peter.O
    Apr 7, 2011 at 12:17
  • 'du' is the better choice... I've just noticed in man du, that it can also report the "apparent file size".... The apparent size of a file is the number of bytes reported by wc -c' on regular files, or more generally, ls -l --block-size=1' or stat --format=%s'. For example, a file containing the word zoo' with no newline would, of course, have an apparent size of 3.
    – Peter.O
    Apr 7, 2011 at 12:50
  • I wanted rather disk space used by files and directories (total size of data inside) directly under tmp (not subdirectories)
    – xralf
    Apr 7, 2011 at 13:34
  • I'm sorry, I'm not in the stage of shell scripting I could understand it yet, so I let it to other users to decide how good answer it is. Thank you for your work. I will study it when I'm better.
    – xralf
    Apr 8, 2011 at 7:43
0
find /tmp -exec du {} + | sort -nr | less 

shows biggest files first, so you can quit as soon as you've seen enough.

0

I use this command for the root folder / to check where the biggest directories are located, but you can use in your case /tmp or any other directory

sudo du / -hxd 1 -t 1M | sort -h
  • -h from human-readable, print sizes in human readable format (e.g., 1K 234M 2G)
  • -x skip directories on different file systems
  • -d from depth, print the total for a directory (or file, with --all) only if it is N or fewer levels below the command line argument
  • -t from threshold, exclude entries smaller than SIZE if positive, or entries greater than SIZE if negative

You must log in to answer this question.

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