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

Hi, Have been trying to develop code that takes an input as a directory (lets say A1). A1 contains 2 files foo.c & moo.c & a directory A2, which contains boo.c The script is expected to drill down into each file inside the directory (& sub-directories) under it, & compress(zip) them & delete the original file. So I want the output to loo like A1-->foo.c.gz , moo.c.gz, A2 -------> boo.c.gz. Anyone kind enough to help me out with this.Ive been trying for awhile now,but without success
  • Comment on How to recursively zip all files insied a directory

Replies are listed 'Best First'.
Re: How to recursively zip all files insied a directory
by Roger (Parson) on Jan 15, 2004 at 06:46 UTC
    I will assume that you are working on a Linux/Unix system.

    The short answer, which is my preferred method:
    tar -zcvf packagename.tar.gz path_to_directory
    This will 'zip' up everything under directory_name into a single archive packagename.tar.gz, while preserving directory structure (assuming you have the GNU version of tar).

    Slightly longer answer:
    find path1/* path2/* -exec gzip {} \;

    This will find all files under path1 and path2 (recursively), gzip the files found (and implicitly removing the original files).

    Now if you want to do that in a perl script -
    ... my @paths = qw! /usr/home/blah /usr/home/foo !; system("/usr/bin/find $_/* -exec gzip {} \\;") for @paths; ...

    Or you could use the File::Find module and then invoke 'gzip' for each of the files found.

      I agree that the gnu tools are probably more of a help here than Perl, but I do have some comments on your examples, for the don't really seem to do what the OP asked for (if I understand the post right).

      tar -zcvf packagename.tar.gz path_to_directory

      This creates a single file, as you state, but the OP is looking for multiple gzip files.

      find path1/* path2/* -exec gzip {} \;

      This will fail too, for the OP states that there are sub directories ;) This will probably work better:

      find path/ -type f -exec gzip {} \;

      The problem with this is that a new process will be started for each file (IIRC). Not very efficient if there are a lot of files. So, to change it a little bit more, I would go for the following approach:

      find path/ -type f -print0 | xargs -0 gzip

      Do note the -print0 and -0. If the files contain spaces, and you leave this out, weird things may happen ;)

      HTH

      --
      b10m
        tar -zcvf packagename.tar.gz path_to_directory

        I thought that was a good way to zip up directories and files recursively. Just to offer an alternative on the off chance that OP is looking for a way to save some space. Zipping everything into a single tar file will certainly save a lot more disk space than zipping them individually.

        find path/ -type f -exec gzip {} \;

        That's a good catch. I forgot about find will return directory names too.

Re: How to recursively zip all files insied a directory
by zentara (Cardinal) on Jan 15, 2004 at 16:18 UTC
    The module PerlIO::gzip might be of help to you, if you have Perl > 5.8. You might also be able to use the following, and loop thru all your files, print to the handle, then unlink them.
    open (my $handle,"gunzip -c $filename |" ) or die $!;