mikejones has asked for the wisdom of the Perl Monks concerning the following question:

In this code when there is only one file found it works with no errors and gives me the output I expect. However, when there is more than one file found I get this output. Any help is always appreciated!

Please enter filesystem name in the form of '/fsname' /cygdrive/c/temp Use of uninitialized value in concatenation (.) or string at file_find +.plx line 24, <> line 1. Use of uninitialized value in concatenation (.) or string at file_find +.plx line 24, <> line 1. Use of uninitialized value in numeric comparison (<=>) at file_find.pl +x line 24, <> line 1. Use of uninitialized value in numeric comparison (<=>) at file_find.pl +x line 24, <> line 1. FileSize in Bytes FileNames over 25 Mbytes =================================================================== 33502125: /cygdrive/c/temp/Setup/Pattern/Share/0x0000000 +4/Copy of lpt$vpn.701 =========================================================== 33502125: /cygdrive/c/temp/Setup/Pattern/Share/0x0000000 +4/lpt$vpn.701

#!/usr/bin/perl use strict; use warnings; use Readonly; use File::Find; use File::Find::Closures qw(:all); #use Data::Dumper; my (@sorted_large_files,@large_files); print qq (\nPlease enter filesystem name in the form of '/fsname'\n); my $fs = <>; chomp ($fs); my @directory = qq($fs); Readonly::Scalar my $t25Mb => 26500000; my( $wanted, $list ) = find_by_min_size ( qq($t25Mb) ); File::Find::find ( { wanted => $wanted, }, @directory ); @large_files = $list->(); @sorted_large_files = sort { -s "$_/$b" <=> -s "$_/$a" } @large_files; print "\nFileSize in Bytes\tFileNames over 25 Mbytes\n"; print map { '=' x length $_,"\n", -s $_,":\t\t$_\n" } @sorted_large_files;

Replies are listed 'Best First'.
Re: File::Find::Closures... help
by Corion (Patriarch) on Dec 15, 2007 at 22:33 UTC

    Did you read the warning message? It talks about line 24. Which, in your code, is the following fragment:

    @sorted_large_files = sort { -s "$_/$b" <=> -s "$_/$a" } @large_files;

    Now, looking at this, there are three variables explicitly mentioned, $a, $b and $_. Looking at the documentation of sort, I find that $a and $b are set and used by the sort() function. Which leaves $_. This could be undefined. Maybe it would be a good idea to investigate the value of $_ and compare that with your expectations.

    It's no real surprise that this works if there is only a single file, because then, the comparison block will never be called, BTW.

      Thank you. I fixed it. I had been working on this for just about an hour, and became tired.
Re: File::Find::Closures... help
by CountZero (Bishop) on Dec 15, 2007 at 23:09 UTC
    Another rather strange construct in your code is my @directory = qq($fs);. Why do you "double quote" the $fs variable? You do a similar thing in find_by_min_size ( qq($t25Mb) ).

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: File::Find::Closures... help
by poolpi (Hermit) on Dec 16, 2007 at 12:46 UTC
    Hello,
    if you just want files over 25 MB, you could try something like this:
    use strict; use warnings; use File::Find; my $dir = 'C:\Download'; my $max_size = 25*1024*1024; #25 Mo opendir DIR, $dir or die; my @large_files = grep {stat("$dir/$_"))[7] > $max_size} readdir(DIR); closedir DIR or die; # or recursively find( \&wanted, $dir ); sub wanted { (stat)[7] > $max_size and push @large_files, $File::Find::name; }

    HTH,
    PooLpi
      When I use the recursive method, I ask for input using the <> operator, I input /var and it spits out errors as such:
      Use of uninitialized value in numeric gt (>) at find_hog2 line 21, <> +line 1. =============================== 103643136: /var/opt/ignite/media/image.iso =============================================

      Line 21 is the sub routine wanted code. I run it in debug mode as /var as input and see these errors:

      main::(find_hog2:17): find ( \&wanted, $fs ); DB<2> p DB<2> n Use of uninitialized value in numeric gt (>) at find_hog2 line 20, <> +line 1. main::wanted() called at /opt/perl/lib/5.8.2/File/Find.pm line + 888 File::Find::_find_dir('HASH(0x404f0fe4)','/var',28) called at +/opt/perl/lib/5.8.2/File/Find.pm line 672 File::Find::_find_opt('HASH(0x404f0fe4)','/var') called at /op +t/perl/lib/5.8.2/File/Find.pm line 1175 File::Find::find('CODE(0x403c10b4)','/var') called at find_hog +2 line 17

      When I use /tmp as input I see no errors with some of these files from /var copied over to /tmp??? The script using File::Find::Closures works with no errors or warnings. please help. thank you!