Wednesday, July 27, 2016

Linux: Zipping Directories into Zipped Files Recursively

Here's a perl script to do it. The idea is from using find2perl, which can construct how perl would do Unix/Linux find command. Using it as a base, a simple script can be very powerful. Note the use of $prune. This is equivalent to find's -prune option. It is used to stop traversing below the current directory.

  1. #!/usr/bin/perl -w
  2. #
  3. # sqzfps.pl -- compress FPS batch files
  4. #
  5. # CJKim, 27-Jul-2016, Created
  6. #

  7. use strict;
  8. use File::Find ();
  9. use vars qw/*name *dir *prune/;
  10. *name   = *File::Find::name;
  11. *dir    = *File::Find::dir;
  12. *prune  = *File::Find::prune;

  13. my $topdir = 'some-top-directory';
  14. my $aging  = 90; # 365;
  15. my $cputhr = 50;
  16. my $cpuchk = 50;
  17. my $dircnt = 0;
  18. $| = 1;

  19. sub cpu_ok
  20. {
  21.     $dircnt++;
  22.     if ($dircnt > $cpuchk) {
  23.         $dircnt = 0;
  24.         while (1) {
  25.             open CPU, 'vmstat 1 2 | awk \'{if (++c == 4) print $15;}\' |';
  26.             my $idle = <CPU>;
  27.             close CPU;
  28.             $idle += 0;
  29.             last if $idle > $cputhr;
  30.             print "Sleeping for 30 seconds since CPU is at $idle% idle...\n";
  31.             sleep 30;
  32.         }
  33.     }
  34.     return 1;
  35. }

  36. sub wanted
  37. {
  38.     # $_ is the file name only
  39.     # $name is the full path
  40.     # $dir is just the directory name
  41.     # $prune may be set to 1 to stop traversing below the current dir

  42.     my ($dev,$ino,$mode,$nlink,$uid,$gid);

  43.     (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_))
  44.     && (-d _)  # directory only
  45.     && (int(-M _) > $aging)  # so many days old
  46.     && ($_ =~ /^\d{16}FF$/)  # fits the name pattern
  47.     && ($prune = 1)  # stop traversing after this one
  48.     && cpu_ok()  # check if we have enough cpu available
  49.     && system "(echo 'Processing $_'; cd $name && zip -m $dir/$_.zip *.* && cd / && rmdir $name)"
  50.     ;
  51. }


  52. # traverse the filesystem
  53. File::Find::find({wanted => \&wanted}, $topdir);



No comments:

Post a Comment