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

Dear Monks:
I have a problem, I have a script that generate a bunch of files from tables in mysql, now sometimes these tables come empty or has a 0kb, so the problem is that I have another script that uses
my $parser = Text::CSV::Simple->new; my @data = $parser->read_file($infile);
So it giving me an error message saying that it cant not read the file, and is because it has no data to read. So my cuestion is how can I delete the files with 0kb?, I know to use unlink but is impossible to know if the next time the same file is comming empty can someone put an example, please thanks!!

Replies are listed 'Best First'.
Re: How to delete empty files
by kyle (Abbot) on Jan 10, 2008 at 20:25 UTC

    You can test whether a file is empty with -z, and -s will return a size (so you can use it to test for "non-empty").

    if ( -s $infile ) { my $parser = Text::CSV::Simple->new; my @data = $parser->read_file($infile); }

    Or...

    if ( -z $infile ) { unlink $infile or die "Can't unlink empty file '$infile': $!"; next FILE; }

    Update: If the files you have are not literally zero size, you may have to stick your parsing in an eval to catch the error and deal with it at that point.

    eval { my $parser = Text::CSV::Simple->new; my @data = $parser->read_file($infile); }; # don't forget the semicolon! if ( $@ ) { if ( $@ =~ /the error you expect/ ) { unlink $infile; next FILE; } # unexpected error! die $@; }

    Have a look at perlvar for documentation on $@ (aka $EVAL_ERROR, if you use English).

Re: How to delete empty files
by leocharre (Priest) on Jan 10, 2008 at 21:52 UTC
    On posix (unix, linux, etc)
    find ./path -type f -empty -exec rm '{}' \;
    Or use File::Find::Rule
    #!/usr/bin/perl use strict; use warnings; use Smart::Comments '###'; use File::Find::Rule; my $f = new File::Find::Rule->file()->empty(); my @files = $f->in($ENV{HOME}); # where to look ### @files for my $abs_file( @files ) { unlink $abs_file or die("cant unlink $abs_file, $!"); } # or use map # map { unlink $_ } @files;
      HI
      your example gave me an error message
      Use of uninitialized value in string eq at C:/Perl/site/lib/File/Find/ +Rule.pm line 586. Use of uninitialized value in substitution (s///) at C:/Perl/site/lib/ +File/Find/Rule.pm line 586. Use of uninitialized value in substitution (s///) at C:/Perl/site/lib/ +File/Find/Rule.pm line 586. invalid top directory at C:/Perl/lib/File/Find.pm line 593.

        It seems that what gave you an error message was "C:/Perl/lib/File/Find.pm line 593", to be more precise 'invalid top directory'.

        What is your directory argument? Are you leaving it at $ENV{HOME} ? Is this environment variable even set on a windows system?

        Add this to the first lines of code, before we instance File::Find::Rule..

        defined $ENV{HOME} or die("ENV HOME is not defined."); print STDERR " # env home is set at $ENV{HOME}\n"; -d $ENV{HOME} or die("ENV HOME is not a directory");
        (You can always bite the bullet and switch to linux. It takes about a year to get comfortable, if you're considering.)

        Furthermore, *DONT RUN THAT SCRIPT*, it's just an example script! :-)

        Substitute $ENV{HOME} with something like 'C:\path\to\where\you\suspect\empty\files\reside'.

        And *read* File::Find::Rule!

        Don't give up so easily- if something does not work, that's when you start 'debugging'. Takes up most of my time, between tests (.t) and errors, and the fact that a third of my code is to check and recheck return values and results.. In the long run it's saved me a lot of sweat and blood.