> I've got a seemingly simple script that is causing me
> to tear my hair out and I'm hoping someone can offer
> some advice. I'll try to keep it short and sweet.
>

I think you should re-examine the order of events and make it very clear
possibly right it in English (or your preferred language) again step wise.
 
> This script reads in the names of all the files in a
> directory given on the command line (the names of
> chapters for a book) into a variable called $thename,
> then reads an html template named  "abstract.html" and
> replaces the string "changeme" in the template with
> the name of the chapter, and finally outputs a new
> file called  "$thename.html". Everything works dandy
> until it's time to replace "changeme" with $thename -
> the output file I get has a "." character instead of
> the value of the variable. Can anyone see what I've
> got wrong? The offending piece is preceeded by the
> comment "I have no idea why this doesn't work".
> 

Just to be clear you want the contents of the template stored into the
files, rather than the previous content of the file to be changed?  I am
not entirely sure where the "." is coming from but see if this helps...

Ah looking further at the script I know where the "." comes from ;-)...

> Thanks a lot,
> Alex
> 
> ************************************
> 
> #!/usr/bin/perl -w
> use strict;
> 

An excellent start!

> my $current=shift @ARGV;
> 
> open READIT,"abstract.html" or die "Cannot open
> abstract.html: $!";
> opendir DH, $current or die "Cannot open $current:
> $!";
> 

I would ungroup these, read the template all at once, then move the
opendir to the spot when you are going to use it, aka just before you
loop over the files.

> #load the contents of abstract.html into an array
> my @load=<READIT>;

Ok read the contents of the template. You can close the template
immediately after this, again I would suggest grouping these three steps
together (aka the open, read, close).  Also note that since you are
wanting to substitute all existences of the string you might want to use
the slurp mode and dispense with the need for the second loop.

> 
> #initialize $count - it might be nice to know
> #how many files we found
> my($count);
> 

Ok. No parentheses are needed (though they don't hurt either) and you
may want to consider setting your count to '0' initially to avoid
uninitialized value warnings.

> #run through the directory
> foreach my $thename (readdir DH) 

readdir returns all files in the directory, including subdirectories and
the . and .. directories.  (now we begin to see where the "." comes from
;-)).  So have a look at,

perldoc -f readdir
perldoc -f grep

So that you can see how to avoid attempting to change the '.' and '..'
directories.  You may also want to view,

perldoc -f glob

>   {
>   print "Found $thename\n";
>   #create a new file called "thename.html"
>   open WRITEIT,">export/$thename.html" or die "Cannot
> create file.html: $!";
>   #find and replace all of the "changeme"
>   #with author name
>   foreach(@load)
>     {
>     #I have no idea why this doesn't work
>     s/changeme/$thename/g;

Actually it does work :-).  However you are changing @load directly, so
the first time it loops through (aka for the '.' file, see above) it is
changing 'changeme' to '.', and storing it back into @load.  On the next
pass 'changeme' no longer exists in @load because you have changed the
array directly, however all of the files will then end up with the same
exact contents.

There are a number of different ways to handle this, the easiest would
be to copy @load to a temporary array before acting on it (though that
isn't necessarily the best from a memory standpoint I doubt it will matter).

>     print WRITEIT;
>     }
>   close(WRITEIT);
>   $count++;
>   }
> print "Found $count files.\n";
> closedir DH;
> close(READIT);
> 
> 

As a learning exercise this is a good tool to work on, having said that
there are probably much better and more Perlish ways to this, check the
archives for substituition examples.

HTH,

http://danconia.org


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to