Re: failed substitution



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
DSC00095d.jpg -> DSC00095d.jpg d
DSC00096e.jpg -> DSC00096e.jpg e
DSC00097f.jpg -> DSC00097f.jpg f
DSC00098g.jpg -> DSC00098g.jpg g
DSC00099h.jpg -> DSC00099h.jpg h
DSC00100i.jpg -> DSC00100i.jpg i
DSC00101j.jpg -> DSC00101_a.jpg j
DSC00102k.jpg -> DSC00102_a.jpg k
DSC00103l.jpg -> DSC00103l.jpg l
...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 :-)

Dani
.



Relevant Pages

  • Re: failed substitution
    ... I wrote a short script ... extension) and substitute it for '_a'. ... the foreach code can at least be shortened to: ... on the full path and not the basename. ...
    (perl.beginners)
  • Re: Error on "cryptorati.com" - adacrypt
    ... Her substitute was modern, cognitive, and yells along with the ... script. ...
    (sci.crypt)
  • Question on perl script.
    ... I am very new to the perl language and don't know much about it. ... two values are being passed to this script. ... The perl command processes the inrptfile by substituting the first line ... How can I make it substitute something completely different ...
    (comp.unix.shell)
  • Re: A subst-antial question
    ... Suppose I have a script: ... I know I have to substitute variables locally before I can set them ... stuff with $foo in it ... An alternative, in Tcl 8.5 (or 8.4 with the dict package), would be to not perform the substitutions locally, but instead to snapshot the environment of the script as a dict, and then send that along with the code to be evaluated remotely using: ...
    (comp.lang.tcl)
  • Question on perl script.
    ... I am very new to the perl language and don't know much about it. ... two values are being passed to this script. ... The perl command processes the inrptfile by substituting the first line ... How can I make it substitute something completely different ...
    (comp.lang.perl.misc)

Quantcast