in reply to Re^4: UNIX command - remove 0 byte file
in thread UNIX command - remove 0 byte file

Let's not forget the OP specifically said 'unix' rather than linux. Filenames with whitespace not being handled with xargs is certainly going to be a problem if this is supposed to be a generic solution. But if the whole file is enclosed in quotes when it has whitespace, rm will handle the argument list properly even if it went thru xargs:
find /path/ -size 0 | perl -e 'while(<>) { chop; s/^(.*\s.*)$/\"$1\"/; + print "$_\n"; }' | xargs -n <whatever-filecount-limit> rm

-M

Free your mind

Replies are listed 'Best First'.
Re^6: UNIX command - remove 0 byte file
by Anonymous Monk on Sep 23, 2005 at 14:15 UTC
    Except that you now have problems if the filename contains double quotes. Or backquotes. Or dollars. If you want to do the quoting yourself, better wrap the arguments in single quotes, after first escaping any single quotes:
    find /path/ -size 0 | perl -ple 's/\x27/\x27"\x27"\x27/g; "\x27$_\x27"' | xargs -n ... rm
    Note the use of \x27 for single quote, lest it ends the argument to perl.

    Of course, if you're going to pipe into perl, there's not much point in calling xargs rm is there? Might as well do the removal from within perl:

    find /path/ -size 0 | perl -nle 'unlink or warn "unlink $_: $!\n"'
    Note that both pieces of code given above still fail on filenames containing newlines.
      the whole point of using xargs in this discussion subthread was to get unix to process the list of removals in one go rather than per file. I am not sure if the same effect can be achieved from perl - unlink will accept multiple arguments (so you could push to array before passing the array to unlink), but I don't know if any optimisation is achieved that way.

      -M

      Free your mind

        xargs was used to eliminate the need to start a different process for each file to be removed. The use of xargs enables you to call rm with a list of file names. But rm will still have to delete the files one by one - the Unix unlink system call accepts only a single argument.

        If you pipe the result of find into perl, you are calling a single process - only one perl instance will be fired. In fact, even less processes will be fired if there are many files to be deleted - xargs will start as many subprocesses as needed to avoid running into system limits with respect to argument lengths. But the perl solution doesn't have that problem, as it's reading the list from standard input, not from @ARGV.