Task

Beginning from the current directory, or optionally from a directory specified as a command-line argument, determine how many files there are of various sizes in a directory hierarchy.



My suggestion is to sort by logarithmn of file size, since a few bytes here or there, or even a factor of two or three, may not be that significant.

Don't forget that empty files may exist, to serve as a marker.



Is your file system predominantly devoted to a large number of smaller files, or a smaller number of huge files?




func traverse(Block callback, Dir dir) {
    dir.open(\var dir_h) || return nil
 
    for entry in (dir_h.entries) {
        if (entry.kind_of(Dir)) {
            traverse(callback, entry)
        } else {
            callback(entry)
        }
    }
}
 
var dir = (ARGV ? Dir(ARGV[0]) : Dir.cwd)
 
var group = Hash()
var files_num = 0
var total_size = 0
 
traverse({ |file|
    group{file.size+1 -> log10.round} := 0 += 1
    total_size += file.size
    files_num += 1
}, dir)
 
for k,v in (group.sort_by { |k,_| Num(k) }) {
    say "log10(size) ~~ #{k} -> #{v} files"
}
 
say "Total: #{total_size} bytes in #{files_num} files"