Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2012
    Posts
    82
    Rep Power
    3

    Making subdirectories


    Hi,
    I have a directory (with bunch of subfolders) on the network.
    Id like to make same folder/subfolders on a local drive.
    I can find all the folder/subfolders but I cannot make them on a local drive.
    Could you help me please?
    Thanks, testerV

    Code:
    #!/usr/bin/perl -w
       use strict;
       use warnings;
       use File::Find;
       
     my $localdrive = 'D:' ; 
     my $netw_dir = "H:\\TSCB\\Docs"; 
    
    sub all_subdirs {
        my $subdir = $File::Find::name;    
        return unless -d $subdir;
        return if ( $subdir eq $netw_dir);
        
                            $subdir =~s{\/}{\\}g ;
                    my @subdir = split/\\/, $subdir ;
                 shift @subdir ;
             unshift @subdir, $localdrive ;
             my $modifsubdir = join "\\", @subdir ;
             print "$modifsubdir\n" ;
        }
     
      find (\&all_subdirs, $netw_dir);
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,376
    Rep Power
    1871
    Well you didn't post your attempt at making the directories.

    Use make_path
    FWIW, Perl won't care that you substituted / for \

    Use XCOPY
    /t : Copies the subdirectory structure (that is, the tree) only, not files. To copy empty directories, you must include the /e command-line option.
    This command and option just clones the tree structure.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2012
    Posts
    82
    Rep Power
    3
    Hi Salem,

    I tried make_path, I know it is supposed to work but it does not.
    Im missing something, it does not re-create all the sub directories.

    Code:
       #!/usr/bin/perl -w
       use strict;
       use warnings;
       use File::Path ;
    
    
     my $old_dir = "C:\\P_test" ;
     my $new_dir = "D:\\P_test" ;   
    
       mkpath([$old_dir, $new_dir], 1, 0777) || die "\n\Couldn't  copy $old_dir '$!'";
    I cannot use xcopy, it is external module and I cannot install external module.
    Thanks, testerV
  6. #4
  7. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,376
    Rep Power
    1871
    > I tried make_path, I know it is supposed to work but it does not.
    ...
    > mkpath([$old_dir, $new_dir]
    It seems to me you used mkpath, not make_path

    Plus, what is "[$old_dir, $new_dir]" supposed to be?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2012
    Posts
    82
    Rep Power
    3
    Hi Salem,
    Thank you for helping me, I really appreciate it!
    As you see my skills in programming not that good, Im working on it.

    I need to keep in sync network Dir (bunch of subdirs) and a local Dir, it is not possible to add any new modules to the Perl.
    My script scans the Network Dir and if any new subDirs created it recreates it on a local drive then it finds new files on the network Dir but it does not want to copy new files to the local Dirs.
    Here is the script:

    Code:
       #!/usr/bin/perl -w
       use strict;
       use warnings;
       use File::Path ;
       
     my $localdrive = 'D:' ;
     
     my $old_dir = "H:\\TSCB\\Docs" ; ## Network Dir ##
     my $new_dir = "D:\\TSCB\\Docs" ; ## Local Dir ##
     
     my $cmd = "xcopy  $old_dir $new_dir /t /e /i "; ## Keeping in sync Network and local dir ##
     system ("start $cmd") or die "'$cmd' failed: $!";
    
     my $todayday = localtime (time);
     my $log = 'D:\\TSCB\\DocsTest_F3.txt' ;  ## Log for any new files found ## 
     my $dir =  "H:\\TSCB\\Docs"; 
    
      open my $log_fh, '>>', $log
        or die "can't open '$log' in append mode <$!>";
                      print $log_fh "$todayday\n" ;
      find (\&find_files, $dir) ;
         sub find_files { 
             if (-M -f $File::Find::name <1) {           ## scaning for a new files ##
            
                my $file_find_name = $File::Find::name ;
                        $file_find_name =~s{\/}{\\}g ;
                        print "$file_find_name\n" ;
                my @file_find_name = split/\\/, $file_find_name ;            
             shift @file_find_name ;
             unshift @file_find_name, $localdrive ; ## replacing "H" netdir drive with "D" local drive##
             pop (@file_find_name) ;             ## removing the file name from the string ##
                my $modif_file_find_name =   join"\\",@file_find_name ;
                 print "$modif_file_find_name\n" ; 
                 print $log_fh "$file_find_name\n\n" ;
                 print $log_fh "$modif_file_find_name\n" ;
    
     my $cmd2 = "xcopy $file_find_name $modif_file_find_name " ; ## trying to copy new files to the ##
        system ("start $cmd2") or die "'$cmd2' failed: $!";      ## local drive but it does not work ##      
               
                          
               }    
            }                     
        close $log_fh ;
        exit ;
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,921
    Rep Power
    1225
    What is preventing you from installing modules?
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,921
    Rep Power
    1225
    The proper solution to this problem is to use rsync, which can be done with or without the Perl script.

    If you don't want to use rsync, then there are a couple other Perl solutions. If you only want to copy/duplicate a directory structure, then the File::Path module would be the most logical approach. However, if you need to also copy the files within each of the directories, then it would be better to use File::Copy::Recursive.

    File::Rsync
    File::Copy::Recursive
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2012
    Posts
    82
    Rep Power
    3
    I might be wrong but it seems to me both File::Rsync and File::Copy::Recursive are the external modules.
    Can't locate File/Copy/Recursive.pm in @INC (@INC contains: C:/Perl64/site/lib C:/Perl64/lib .)
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    May 2007
    Posts
    765
    Rep Power
    929
    I don't see why you're going through all these contortions with perl and various modules.

    What's wrong with a simple batch file? From your description, this should solve your problem:
    Code:
    rem save this as some_name.bat
    xcopy H:\TSCB\Docs D:\TSCB\Docs /E /Y
    (and would have solved your problem 7 posts ago if you had clicked the link salem posted)
    sub{*{$::{$_}}{CODE}==$_[0]&& print for(%:: )}->(\&Meh);
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2012
    Posts
    82
    Rep Power
    3
    Thank you Omega!
    Yes, I could make same batch and run it but I'm learning Perl and I'd like to write a script that will do the same thing.
    make_path does not copy all the subdirs from the "Docs"folder. I'm doing something wrong just do not know what it is.

    Code:
    #!/usr/bin/perl -w
       use strict;
       use warnings;
       use File::Path qw(make_path) ;
    
      make_path('H:\\TSCB\\Docs', 'D:\\TSCB\\Docs', {
      verbose => 1,
      mode => 0711,
      })or die $! ;
       
        exit ;
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    May 2007
    Posts
    765
    Rep Power
    929
    I see. The problem is that make_path doesn't do copying at all, it takes a list of directories and creates them:

    Originally Posted by perldoc File::Path
    The make_path function creates the given directories if they don't exists before, much like the Unix command mkdir -p.

    The function accepts a list of directories to be created. Its behaviour may be tuned by an optional hashref appearing as the last parameter on the call.
    To use make_path, you'll need to assemble a list of every directory you want it to create. You might do that by pushing the directories found by File::Find into an array, then supplying that to make_path.

    To save you to trouble of munging the paths in the wanted sub, here's a trick:

    Code:
    # Assume a directory structure like
    # parent
    # +-- child
    #     +--- file 
    chdir '\parent';
    find( { wanted => sub { print $_; }, no_chdir => 1 }, 'child' );
    With the "no_chdir" option, $_ will include a full path not just the filename and it will base those paths with respect to the relative path the "child" based on the current directory "parent". E.g., you'll get $_ = "child\file" making it assemble a path rooted in a different directory.
    sub{*{$::{$_}}{CODE}==$_[0]&& print for(%:: )}->(\&Meh);
  22. #12
  23. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2012
    Posts
    82
    Rep Power
    3
    Thank you Omega!
    I found a perl script, changed it little bit and it copies my directory now. I do not understand few lines :
    Code:
     for $list(0..$#dirs) 
    ($ndir."\\".$dirs[$list])
    ($dir."\\".$dirs[$list])
    But the rest of it works.Now I need to copy all updated files from the Network dir to the local dir. Any idea how I can do that?
    Thanks, testerV

    Code:
        #!/usr/bin/perl -w
           use strict;
           use warnings;
        
        use File::Copy;
        use File::Find;
        use File::Path qw(make_path) ;
        
        my $netDir = q{H:\TSCB\Docs};
        my $locDir = q{D:\TSCB\Docs};
        
        &myDirTofind($netDir);
        exit 0; 
        
        sub myDirTofind  {
                my ($dir) = @_;
                my (@dirs,$list);
                opendir(DIR,$dir) || warn "can't open the directory $dir: $!\n";
                @dirs=grep {!(/^\./) && -d "$dir\\$_"} readdir(DIR);        
                closedir (DIR);
                for $list(0..$#dirs) {
                        mkdir ($locDir) unless -d $locDir;
                            my $ndir = $dir;
                               $ndir =~ s"O:\\T2000\\Scripts"C:\\T2000\\Scripts";                
                    make_path ($ndir."\\".$dirs[$list]);
                    &myDirTofind($dir."\\".$dirs[$list]); }
                return 1;
              }
        exit ;
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,921
    Rep Power
    1225
    I must assume that you didn't even look at either if the 2 modules I pointed out and linked to. The File::Copy::Recursive module will copy the directory structure and files without having to use your myDirTofind() sub.
  26. #14
  27. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2012
    Posts
    82
    Rep Power
    3
    Hi Fish,
    I do not have that much knowledge to ignore you or Omega.
    Anyway, I tried it (see my replies ):

    Code:
       use File::Copy::Recursive qw(dircopy) ;
    
             my $netDir = 'H:\\TSCB\\Docs';
             my $locDir = 'D:\\TSCB\\Docs';
        dircopy($netDir,$locDir) or die $!;
    I got error:
    Code:
    Can't locate File/Copy/Recursive.pm in @INC (@INC contains: C:/Perl64/site/lib C:/Perl64/lib .)
    I assumed this is an external module. It is not possible to install any modules on these machines.

    Thanks, testerV
  28. #15
  29. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,921
    Rep Power
    1225
    The reason you gave me in your PM why you can't install modules is a bit weak.

    1) You could build an install script that checks for missing dependencies and installs them as needed.

    2) If the non core modules are pure Perl, as is the case with File::Copy::Recursive, you could simply include it as part of your app.

    3) You could use PAR::Packer or a 3rd party app such as perl2exe to package your app and all required non core modules as a standalone executable and deploy that single executable.

    4) If none of the above options are acceptable, then perl is the wrong language to use for your app. You should use a language that compiles its source code to binary executables.
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo