Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

UNIX command - remove 0 byte file

by darrengan (Sexton)
on Sep 23, 2005 at 06:44 UTC ( #494416=perlquestion: print w/ replies, xml ) Need Help??
darrengan has asked for the wisdom of the Perl Monks concerning the following question:

Dear Fellow Monks....

This is a unix command question and i know i posted in a totally different planet... some how i find you guys helpful :P
How do i remove file with 0 byte?
something like:
system (rm 0 size); ??

Cheers!

Comment on UNIX command - remove 0 byte file
Re: UNIX command - remove 0 byte file
by bart (Canon) on Sep 23, 2005 at 06:50 UTC
    This is a perl forum so I'll answer with some perl code...
    foreach(glob('*.*')) { unlink if -f and !-s _; }
    You can change the glob pattern to taste; you may even include a relative or absolute path.

      Methinks you have an operator precedence bug here. On second thoughts, what you have is pseudocode (unless you intended it to be a perl 6 style junction :). Should be:

      foreach(glob('*.*')) { unlink if (-f $_) && !-s _; }

      --

      Oh Lord, won’t you burn me a Knoppix CD ?
      My friends all rate Windows, I must disagree.
      Your powers of persuasion will set them all free,
      So oh Lord, won’t you burn me a Knoppix CD ?
      (Missquoting Janis Joplin)

Re: UNIX command - remove 0 byte file
by monarch (Priest) on Sep 23, 2005 at 07:05 UTC
    #!/bin/sh for file do if [ ! -f ${file} ]; then continue fi STR=`cat ${file}` if [ -z "${STR}" ]; then rm ${file} fi done
Re: UNIX command - remove 0 byte file
by newroz (Monk) on Sep 23, 2005 at 07:34 UTC
    Insert appropriate directory path instead of $directory then cast the command.
    perl -e '!-s&&unlink $_ for<$directory/*>'
Re: UNIX command - remove 0 byte file
by Zaxo (Archbishop) on Sep 23, 2005 at 07:37 UTC

    Here's a command-line version of bart's excellent solution:

    src]$ mkdir empty; cd empty; touch {a,b,c}.{a,b,c} empty]$ echo foo > d.d empty]$ ls a.a a.b a.c b.a b.b b.c c.a c.b c.c d.d empty]$ perl -e'-f and !-s _ and unlink for @ARGV' *.* empty]$ ls d.d empty]$
    Slightly golfier is good on the command line; this is marginally shorter and calls unlink only once, on a list,
    empty]$ perl -e'unlink grep -f && !-s _, @ARGV' *.*
    If you don't have to worry about named pipes and other filesystem exotica, you can reduce that to,
    empty]$ perl -e'unlink grep !-s, @ARGV' *.*
    since directories are at least one block long.

    After Compline,
    Zaxo

      Whoa, you never know what little tid bits you'll find lying around the monestary. I never knew about the shell {1,2,3}.{a,b,c} construct.

      Bravo!

      Hazah! I'm Employed!

        Glad you like it. That works with perl glob, too.

        $ perl -e'print "@{[glob q({c,t}{a,o}{t,re})]}$/"' cat care cot core tat tare tot tore $

        After Compline,
        Zaxo

Re: UNIX command - remove 0 byte file
by Moron (Curate) on Sep 23, 2005 at 08:24 UTC
    Or do you mean all files in a tree with 0 bytes? And then there is the question of whether hidden files (.something) should be included in the search. The unix way is the tersest (this example includes hidden files)
    find /whatever/path/ -size 0 -exec rm {} \;
    And the perl way, with hidden files filtered out this time:
    Purge( '/whatever/path' ); sub Purge { my $dir = shift; open my $dh or die "$!, for $dir"; for my $file ( grep !/^\./, readdir $dh ) { my $path = "$dir/$file"; if ( -d $path ) { Purge( $path ); } else { ( -z $path ) and unlink $path; } } close $dh or die "$!, for $dir"; }

    -M

    Free your mind

      find /whatever/path/ -size 0 -exec rm {} \;
      One comment. "-exec" is generally not the best idea unless you care that your command is executed on exactly one file at a time. The problem with exec is that it spawns a new process for every file that it finds. Which isn't bad if the process takes a long time; the tiem spent in starting a new process is shadowed by the run time of the executable. However, in the case of rm, the operation is very quick, so the converse is true.

      In this case, we have a couple of options. In looking at my local find man page, I see that find has a -delete option. This may be a Linux-ism though, as I don't seem to remember this on Solaris. Failing that, we always have xargs. And so, your invocation becomes either find . -size 0 -delete or find . -size 0 | xargs rm. I've seen the xargs version speed up an invocation of find by roughly an order of magnitude. YMMV.

      thor

      Feel the white light, the light within
      Be your own disciple, fan the sparks of will
      For all of us waiting, your kingdom will come

        -delete is indeed a linuxism as opposed to a unix option of find, but xargs is indeed available under e.g. Solaris.

        A potential problem with using xargs is that although it means only one execution of rm which bodes better performance, it also converts everything read in from the pipe into a single argument list, which above a certain limit will cause rm to Segmentation Fault, whereas -exec is guaranteed to work for an unlimited number of files. The choice therefore depends on the particular environment it is being applied to.

        -M

        Free your mind

Re: UNIX command - remove 0 byte file
by darrengan (Sexton) on Sep 23, 2005 at 08:31 UTC
    Thanks on all the advise and scripts...
    I actually need a perl script to delete 0 byte file but i still do not quite understand the sample provided by you guys...
    thanks...
      If you need to do it from a Perl program, I would do:
      # Remove all empty files in '$dir' and below. my $dir = "/some/path"; system "find '$dir' -size 0c | xargs rm";
      This should work on a Unix system, and your question indicates you are on a Unix system.

      And that is of course assuming that you want to find and then remove 0 byte files. But to be honest, your question isn't quite clear, and perhaps you mean something else.

Re: UNIX command - remove 0 byte file
by Anonymous Monk on Aug 15, 2011 at 14:55 UTC
    Hello All!

    I am also confused. the excerpt from the post I would like to discuss is:

    If you need to do it from a Perl program, I would do:

    # Remove all empty files in '$dir' and below.

    my $dir = "/some/path";

    system "find '$dir' -size 0c | xargs rm";

    To write a perl script to make this work, it would look like:

    !#/bin/perl

    # To remove all 0 byte file in a folder

    my $dir = "/home/bob/mytemp";

    system "find '$dir' -size 0c | xargs rm"; </P

    This does not work. I can type this from command line:

    find . -type f -size 0 | xargs rm

    and it deletes all zero byte file.

    I can type from cmd line:

    find /home/bob/mytemp -type f -size 0 -exec rm {} \;

    and it removes all 0 byte file.

    BUT,,, when I put it in a perl script, it errors or just does not work.

    Can anyone explain why? Thanks so much

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://494416]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (9)
As of 2014-08-29 20:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (287 votes), past polls