Home
History
Comparisons
Examples
Documentation
  Help File
Download
News
Wish List
Soapbox

Project:
  Forums
  Tracker
  CVS

Hosted by:
  Sourceforge
  VA Linux

Author

Hawk / Ftwalk Examples: ftdu

This script provides an equivalent implementation of the UNIX du program in Ftwalk. The only change is that we've added a new option, -nN, which if specified only reports disk space for files that have been modified in the last N days.

BEGIN {
    # get option switches from command line. the option switches are
    # single character flags, so each option switch string is separated
    # into characters which are tested in the switch statement.
    while (Opt = getopt) {
        for (i = 1; i <= Opt.length; i++) {
            switch (Opt.substr(i, 1)) {
              case "s": Summarize = true  # only print totals for args
              case "a": AllFiles = true   # print info for all files
              case "k": KBlocks = true    # convert to 1024-byte blocks
              case "l": local             # limit search to local machine
              case "m": mount             # limit search to file system
              case "L": follow            # follow symbolic links
                # new feature: if -n30 only summarize files changed
                # in last 30 days. number must be part of same option
                # string, not separated by space.
              case "n": MaxDays = float(Opt.substr(i + 1)); i = n
              default:
                die("unrecognized option: -%(Opt.substr(i, 1))\n"
                  "usage: ftdu [-aklmsL] [path] ...")
            }
        }
    }
    # use depth-first search, so all files under a directory will be
    # summarized before the directory itself is handled.
    depth
    # allocate list for files with multiple links to guard against
    # reporting more than once.
    Links = list
    # change output field separator to tab
    OFS = "\t"
}

# print out the size and pathname of the current file. if file is a
# directory the size is the accumulated size of all files under the
# directory (collected under Space); otherwise the size is the size
# of the file itself.
function du_print() {
    if (isdir)
        Sz = Space[path]
    else if (MaxDays && mtime > MaxDays)
        return
    else
        Sz = sizeb
    # if -k option, convert 512-byte blocks to 1024-byte blocks.
    # divide by 2.0 and round up.
    if (KBlocks)
        Sz = ceil(Sz / 2.0)
    print(Sz, path)
}

# test/action pair checks for regular files with multiple hard links.
# only count such files once. the Links list keeps track of all such
# files seen so far. directories are not tested since the extra link
# files (. and ..) are excluded by the file search algorithm.
links > 1 && !isdir {
    # each file is uniquely identified by device/inode numbers
    Nm = sprintf("%d:%d", st_dev, st_ino)
    if (Nm in Links)
        next        # already counted
    Links += Nm     # add to list to catch further references
}

# test/action pair used by all files (except extra links skipped by
# next above). the disk space used is added to the tally of each
# parent directory, back to the original command line argument
# (available in FILENAME).
{
    Blks = (MaxDays && mtime > MaxDays) ? 0 : sizeb
    Nm = path
    if (isdir || Nm == FILENAME)
        Nm += "/Z"  # add something for dirname to chop off
    do {
        Space[Nm = dirname(Nm)] += Blks
    } while (Nm != FILENAME)

    # output depends on option switch variables
    if (Summarize) {
        if (path == FILENAME)
            du_print
    }
    else {
        if (isdir || AllFiles)
            du_print
    }
}