On 24 Nov 2006 at 23:55, D. Bolliger wrote:

> Beginner am Freitag, 24. November 2006 14:48:
> > Hi,
> >
> > I have a number of jpegs I wanted to rename. I wrote a short script
> > to do it but the new file name is not always generated correctly. The
> > script should find the last letter in the filename (before the
> > extension) and substitute it for '_a'.
> 
> Hi Beginner
> 
> I assume that you mean "substitue with _a".
> 
> > If you look at the results below you'll see that 'a' and 'b' fail but
> > 'c' worked. I don't understand why.
> >
> > DSC00092a.jpg -> DSC00092a.jpg a
> > DSC00093b.jpg -> DSC00093b.jpg b
> > DSC00094c.jpg -> DSC00094_a.jpg c
> > ...snip
> >
> > Here the script, there isn't much to it. Can anyone explain why the
> > substitute fails?
> 
> I should not mention that in the public ;-) but, just to demonstrate one way 
> to search for a reason for a malfunction:
> 
> Because I did not see an error at first glance, I...
> 
> > #!/bin/perl
> > # Active State 5.8.6.811
> >
> > use strict;
> > use warnings;
> > use File::Basename;
> >
> > my $dir = 'D:/Temp/jpegs/thumbs/';
> > my @files = glob("${dir}*.jpg");
> 
> ...replaced these two lines with simply 
> 
>    my @files=qw(DSC00092a.jpg DSC00094c.jpg); # etc
> 
> and everything worked fine. 
>    Then, I created these files in the current directory, and again everything 
> worked fine.
> 
> Then, I made a subdirectory, moved the file over, ...
> 
> 
> > foreach my $f (@files) {
> >     (my $l) = ($f =~ /([a-z]|[a-z][a-z])\.jpg/);
> >     (my $new = $f) =~ s/$l/_a/;
> 
> ...placed here a 
> 
>    warn "new=$new";
> 
> and got (excerpt):
> 
> new=/home/d_ani/ramsch/thumbs/DSC00092a.jpg at ./script.pl line 17. # !!
> new=/home/dani/ramsch/thum_as/DSC00093b.jpg at ./script.pl line 17. # !!
> new=/home/dani/rams_ah/thumbs/DSC00094c.jpg at ./script.pl line 17. # !!
> new=/home/dan_a/ramsch/thumbs/DSC00100i.jpg at ./script.pl line 17. # !!
> new=/home/dani/ramsch/thumbs/DSC00101_a.jpg at ./script.pl line 17.
> 
> >     my $basef = basename($f);
> >     my $basenew = basename($new);
> >     print "$basef -> $basenew $l\n";
> > }
> 
> And now it's extraordinary obvious that the error is
> 
>   (my $new = $f) =~ s/$l/_a/;
> 
> which simply searches for the first char contained in $l and replaces it 
> with '_a'. This makes the malfunction dependent from the contents in $dir.
> 
> Instead, this line should be more specific, f.ex:
> 
>   (my $new = $f) =~ s/$l\.jpg$/_a\.jpg/;
> 
> (Note that I anchor with $ since "DSC00092a.jpg" is a valid path name :-) )
> 
> Of course it would have been sufficient to only present this last 
> substitution 
> to lead you to a "aha!", but I think it's important to have a personal 
> strategy to search for errors in the dark :-)
> 
> 
> btw, the foreach code can at least be shortened to:
> 
> foreach my $basef (map basename ($_),  @files) {
>   (my $l) = ($basef =~ /([a-z]{1,2})\.jpg$/);
>   # above line is still problematic: What if the match failes?
> 
>   (my $basenew = $basef) =~ s/$l\.jpg$/_a\.jpg/;
>   print "$basef -> $basenew $l\n";
> }
> 
> and certainly optimized further in several ways (f.ex if you don't need the 
> last print statement, $l could possibly be eliminated), but I'm so tired and 
> brain dead at the time :-)

Thanx Dani and John,

I should have realised that the that I was making the substitiution 
on the full path and not the basename.

I appreciate you showing me how to shorten the code. Can I ask if I 
am reading it right.

 foreach my $basef (map basename ($_),  @files) {
    (my $l) = ($basef =~ /([a-z]{1,2})\.jpg$/);

Does this basename everything in @files and make it $basef?


In John's example I am not sure what is happening with this RegEx:
    ( my $new = $f ) =~ s/([a-z]{1,2})(?=\.jpg\z)/_a/;

There are 2 sets of parentheses but one lvalue, $new. So is that any 
character a-z, 1 or 2 times and the ? mean 1 or more times?  What is 
the \z switch here? I can find it is perlre.

Thanx again.
Dp.




-- 
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