The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/bin/perl
use warnings;
use strict;
use 5.006;

our $VERSION = '0.04';

=head1 NAME

fdu - Estimate file space usage (using Filesys::DiskUsage)

=head1 SYNOPSIS

  fdu [OPTION]... [FILE]...

=head1 DESCRIPTION

Summarize disk usage of each FILE, recursively for directories.

=head1 OPTIONS

=head2 -L

Dereference all symbolic links.

=head2 -X PATTERN

Exclude files that match PATTERN.

=head2 -h

Print sizes in human readable format (e.g., 1K 234M 2G).

=head2 -H

Likewise, but use powers of 1000 not 1024.

=head2 -s N

Assume sector size of N.

=head2 -l N

Assume link size of N (ignored if -L).

=head2 -s N

Assume sector size of N.

=head2 -l N

Assume link size of N (ignored if -L).

=head2 -m MAX-DEPTH

Print the total for a directory (or file) only if it is N or fewer
levels below the command line argument.

=head2 -t N

If printing sizes in human readable format, truncate all values by the
Nth place.

Truncate 

=cut

use Getopt::Std qw(getopts);
use lib 'blib/lib';
use Filesys::DiskUsage qw/ du /;

our %opts    = get_options();

#show_help()             if $opts{ };
show_version()          if $opts{v};

my %files = du( { 'make-hash' => 1, %opts }, @ARGV );
my $human = $opts{'human-readable'} || $opts{'Human-readable'};

my $total = 0;
for (sort keys %files)
{
    print "$_ => $files{$_}\n";
    $total += $files{$_} unless $human;
}
print "\nTotal: $total\n" unless $human;

# subroutines

sub get_options {
  my %opts;
  my %opts_to_du = (
                    L   => 'dereference',
                    X   => 'exclude',
                    h   => 'human-readable',
                    H   => 'Human-readable',
                    'm' => 'max-depth',
                    's' => 'sector-size',
                    l   => 'symlink-size',
                    t   => 'truncate-readable',
                   );

  getopts('hHLm:t:vX:s:l:', \%opts );

  for my $key ( keys %opts ) {
    $opts{$key} = 1 unless defined $opts{$key}
  }

  map { $opts_to_du{$_} => $opts{$_} } keys %opts;
}

###

sub show_help { # unfortunately, this is never used, for now
  die "Usage: fdu file1 file2
fdu: estimate file space usage (using Filesys::DiskUsage)

Options:
  -           displays this messages and exit
  -v          show version and exit

  -L          dereference
  -X PATTERN  pattern to exclude
  -h          human-readable format
  -H          human-readable format with powers of 1000
  -m MAXDEPTH max-depth
  -s SIZE     sector-size
  -l SYMSIZE  symlink-size
  -t TRUNCATE truncate-readable
"
}

###

sub show_version {
  die"fdu version $VERSION\n";
}

=head1 AUTHOR

Jose Alves de Castro, E<lt>cog@cpan.orgE<gt>

=head1 COPYRIGHT AND LICENSE

Copyright 2004 by Jose Alves de Castro

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself. 

=cut