I wrote a simple version of the UNIX directory disk usage tool du
(disk usage). Its output should be exactly the same as du -sh
. Call it with the name of a file or folder.
Update: This is the second version, using a better method for the bytesize output and guessing the system’s blocksize.
def du_format size size = Kernel.Float size magnitude = (Math.log(size) / Math.log(1024)).floor unit = 'BKMGTPEZY'[magnitude, 1] size /= 1024.0 ** magnitude sizestr = '%3.1f' % size sizestr = size.round.to_s.rjust(3) if sizestr[/\d+.\d/] && $&.size > 3 sizestr + unit end
BLOCK_SIZE = File.stat($0).blksize rescue 1
def read_file path begin stat = File.stat path rescue SystemCallError return File.symlink?(path) ? BLOCK_SIZE : 0 end if stat.file? stat.size + (-stat.size % BLOCK_SIZE) elsif stat.directory? read_dir path else 0 end end
def read_dir path size = 0 Dir.chdir path do for file in Dir.entries '.' next if file == '.' || file == '..' size += read_file file end end size rescue SystemCallError 0 end
path = ARGV.first || '.' size = read_file path puts "%s\t%s" % [du_format(size), path]
If you want to check how good it matched du
output for you, try
find ~ -depth 1 -exec du -sh {} \; -exec ruby dirsize.rb {} \;
or something. It’s about half as fast as du
on Mac OS X. I like the recursion :)