in reply to recursive directory question

First, thanks for all the suggestions and comments. Particularly merlyn for his File::Find solution and jarich for his excellent explanation of my code and it's errors

This is now the most up to date version of the problem:

#!/usr/bin/perl -w # Author: Ryan Scadlock with significant help # from Perlmonks merlyn, jarich, and Fletch # Date: 6 July 2002 # Description: (UNIX only) Recurses through a directory structure and # checks if more than half of the file in that directory have been use +d # in the past 180 days. The path of diectory which are predominately # unused is apprended to a list. use File::Find; # file's date of last access is determining factor my %access; #$access{$dirname}{old}, $access{$dirname}{new} my $top = shift || "."; find sub { return unless -f; $access{$File::Find::dir}{-A _ > 180 ? 'old' : 'new'}++; #date }, $top; # put your topdirs here for (sort keys %access) { if ($access{$_}{old} > $access{$_}{new}) { print "$_ has more old than new\n"; } }

A few problems remain. 1)This script needs to output to a file. The tree it will be searching contains thousands of directories; which would make that "print" scroll off the top. 2)There is a problem with the line
($ages{$_}{old} > $ages{$_}{new}) {
I get "use of unintialized value in numeric gt at ..." message from the interperter.
However, I am many hours closer to a working script than I was. So: Thanks

Replies are listed 'Best First'.
Re: Re: recursive directory question
by jarich (Curate) on Jul 09, 2002 at 01:02 UTC
    # Usage: find_archive [directory 1] [directory 2] ... [directory n] use File::Find; # file's date of last access is determining factor my %access; #$access{$dirname}{old}, $access{$dirname}{new} my @top_dirs = @ARGV; # allows us to search over mul +tiple trees # eg /home/jarich/ /home/aquil +o/ if # specified on command line push @top_dirs, "." unless @top_dirs; # default behaviour my $results_file = "./archive_results.txt"; find sub { return unless -f; $access{$File::Find::dir}{-A _ > 180 ? 'old' : 'new'}++; }, @top_dirs; my @results; for (sort keys %access) { $access{$_}{old} ||= 0; # defaults to avoid warnings $access{$_}{new} ||= 0; if ($access{$_}{old} > $access{$_}{new}) { push @results, "$_"; # keep results rather than pri +nting } } # Dump all to file. open RESULTS, "> $results_file" or die "Failed to open $results_file for writing: $!\n +"; print RESULTS join("\n", @results), "\n"; close RESULTS;

    Update: Added $! to open statement and extra newline.

      open RESULTS, "> $results_file" or die "Failed to open $results_file for writing\n"; print RESULTS join("\n", @results); close RESULTS;
      That's missing the final newline (a common mistake). Perhaps you wanted:
      open RESULTS, ">$results_file" or die; print RESULTS "$_\n" for @results; close RESULTS;
      And as for:
      $access{$_}{old} ||= 0; # defaults to avoid warnings $access{$_}{new} ||= 0; if ($access{$_}{old} > $access{$_}{new}) { push @results, "$_"; # keep results rather than pri +nting }
      I'd recast that as:
      if (($access{$_}{old} || 0) > ($access{$_}{new} || 0)) { push @results, "$_"; # keep results rather than pri +nting }
      mostly because I hate changing values when all I'm really trying to do is test them. One of the many reasons why I'm not religious about enabling -w.

      -- Randal L. Schwartz, Perl hacker