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

Forgive me, but I know nothing about Perl other than listening to programmers at previous place of employment rave about what they could accomplish with Perl.

Would anyone be able to point me in the right direction and possibly recommend some books that would help me?

I have this project that needs to be completed in the next week or two (that reoccurs annually) that requires me to build a directory structure for our data. It seems like it should be so easy to put something like this together but I have no clue where to start.

An example of the directory structure is:

2005\0_09
2005\10_19
2005\20_29\20\
2005\20_29\21\
2005\20_29\22\addendums
2005\20_29\22\current
2005\20_29\22\archive

So each of the 2005 clients, in this case client 22 in range 20 through 29, requires 3 directories (addendums, current and archive). But we have 10,000 clients and each requires us to organize and build subdirectories from a predetermined client list that changes annually.

Is there a way I can supply the client list in one file, the sub directory names in another, and run the script to create the directories on the server?

Any help or direction would be greatly appreciated.

Thank you in advance.

Dana

Retitled by davido.

  • Comment on How to automate construction of directories?

Replies are listed 'Best First'.
Re: How to automate construction of directories?
by bart (Canon) on Jan 05, 2005 at 21:30 UTC
    Sure you can. Let's assume the client list is in clients.txt, the subdirectory list in subdirectories.txt, one entry per line. You can read the clients like this:
    open IN, '<', 'clients.txt' or die "Can't open file 'clients.txt': $!" +; @clients = <IN>; chomp @clients;
    Idem for the subdirectories:
    open IN, '<', 'subdirectories.txt' or die "Can't open file 'subdirecto +ries.txt': $!"; @subdirs = <IN>; chomp @subdirs;

    Now, it's time to "multiply" the clients with the subdirectories, meaning combining each of one array with each of the other array, and create the subdirectories for each result.

    Note that perl actually doesn't mind you trying to create a directory that already exists.

    my $year = 2005; mkdir $year, 0755; foreach my $client (@clients) { $client =~ /(\d*)\d/ or next; # we need digits; my $range = "${1}0_${1}9"; -d "$year/$range" or mkdir "$year/$range", 0755 or die "Can't create directory '$year/$range': $!"; -d "$year/$range/$client" or mkdir "$year/$range/$client", 0755 or die "Can't create directory '$year/$range/$client': $!"; foreach my $subdir (@subdirs) { -d "$year/$range/$client/$subdir" or mkdir "$year/$range/$clie +nt/$subdir", 0755 or die "Can't create directory '$year/$range/$client/$subdir +': $!"; } }
      Good, but I'd simplify by using a module:
      use File::Path; my $year = 2005; for my $client ( @clients ) { my( $clump ) = $client =~ /(\d*)\d/ or next; # we need digits; my $range = $clump.'0_'.$clump.'9'; mkpath([ map "$year/$range/$client/$_", @subdirs ]); }
      (Untested)
Re: How to automate construction of directories?
by ambrus (Abbot) on Jan 05, 2005 at 21:16 UTC
Re: How to automate construction of directories?
by husker (Chaplain) on Jan 05, 2005 at 21:41 UTC
    The Llama book is, in my opinion, the best place to start leaning Perl. (The second best is to join Perlmonks, but I see you already have!)
      Thank you all very much for your help. I will take a look at the samples provided, and all the documentation I can find, and make a go of it. Thank you again.
Re: How to automate construction of directories?
by gaal (Parson) on Jan 05, 2005 at 21:25 UTC
    It wasn't clear if "a client" is just a number, and if you need the three directories made for each of the 10,000 clients.

    Also, do you always group together directories in chunks of ten? If the answer to all these is "yes", then something like this may do the trick:

    my $chunk_size = 10; foreach my $chunk (0 .. 10_000 / $chunk_size) { my $start = $chunk * $chunk_size; my $end = $start + $chunk_size - 1; # I say "${start}" to keep it from being interpreted as $start_ mkdir "2005/${start}_$end" or die "can't mkdir: $!"; foreach my $client ($start .. $end) { mkdir "2005/${start}_$end/$client" or die "can't mkidir: $!"; foreach (qw/addendums current archive/) { mkdir "2005/${start}_$end/$client/$_" or die "can't mkidir +: $!"; } } }

    (I didn't test this.)

      It might be a good idea to add leading zeroes to the numbers, so the file-system sorts the directories in a more legible way. You would rather like it to be
      • 2005/00000_00010
      • 2005/00010_00020
      • 2005/00020_00030
      • 2005/00030_00040
      • ...
      than
      • 2005/0_10
      • 2005/10_20
      • 2005/100_110
      • 2005/1000_1010
      • ...
      • 2005/20_30
      • 2005/200_210
      • 2005/2000_2010
      • ...

      CountZero

      "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

        It might :)

        But it wasn't specified, and the OP actually gave a contrary example.

        (Requirements are always the hard part!)