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

More specifically.
the file name is broken down like this: a 3 digit ID. In this case 222 and then a 6 digit ID code in this case it's starting at 000100 and should increment by 1. The next one would be 000101. And the last 2 digits need to remain intact to the file as to which image it is 01, 02, 03, 04 etc. So the 222 will remain the same, as should the image numbers, is the 6 digit ID in the middle that needs to have a new sequencial order added to it. I hope this helps, and I appreciate the input.

K

I just don't seem to get this to work right. I'm trying to make a program to make my job easier, but as a result i've just wasted a bunch of time wandering aimlessly through this code. What i need is a program to change multiple file names that run in a sequencial order with an additional two digit image number for only certain files added to the end. For instance, I may have:
22200010001
22200010101
22200010102
22200010103
22200010201
But I need these files (and a few hundred others) changed to something like this:
22200000101
22200000201
22200000202
22200000203
22200000301
If anyone understands my ramblings and can point me in the right direction, i'd appreciate it. K

Edited by Arunbear: Changed title from 'Help Needed', as per Monastery guidelines

Replies are listed 'Best First'.
Re: Mass file renaming
by BrowserUk (Patriarch) on Jul 19, 2005 at 20:11 UTC

    Like this?

    print for map { $_ - 9900 } 22200010001, 22200010101, 22200010102, 22200010103, 22200010201;; 22200000101 22200000201 22200000202 22200000203 22200000301

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.

      If both the new and the old value at the same time (e.g. if you want to call rename), the soluton in this post's parent can be refactored as:

      @old_names = ( 22200010001, 22200010101, 22200010102, 22200010103, 22200010201 ); foreach (@old_names) { my $old_name = $_; my $new_name = $_ - 9900; ... do something ... }
Re: Mass file renaming
by Zaxo (Archbishop) on Jul 19, 2005 at 20:08 UTC

    You need to specify exactly what transformation you want to make on the file names. Write that as a sub,

    sub name_transform { my ($oldname, $newname) = shift; $newname = ;# whatever return $newname; }
    Then rename your files with something like this,
    for (glob '/path/to/222*') { rename $_, name_transform($_); }

    After Compline,
    Zaxo

Re: Mass file renaming
by CountZero (Bishop) on Jul 19, 2005 at 20:03 UTC
    If you can explain to us the general pattern of the filenames to be changed and the rule used to change them into another file name, I'm sure someone will be able to write a nice regex for it.

    CountZero

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

Re: Mass file renaming
by sasikumar (Monk) on Jul 19, 2005 at 21:16 UTC
    Hi,

    Might be this would work.
    sub TransformFileName($) { my $FileName=shift; my $IdExp1=$FileName; my $IdExp2=$FileName; my $IdExp3=$FileName; $IdExp1=~s/(\d\d\d)(.*)?/$1/; $IdExp2=~s/(\d\d\d)(\d\d\d\d\d\d)(.*)?/$2/; $IdExp3=~s/(\d\d\d)(\d\d\d\d\d\d)(\d\d)/$3/; my @Transform=split(//,$IdExp2); my $value=0; for(my $i=0;$i<@Transform;$i++) { $value+=$Transform[$i]; } my @Nsize=split(//,$value); my $Nzero=5; $IdExp2=$value; for (my $i=0;$i<$Nzero-@Nsize;$++) { $IdExp2='0'.$IdExp2; } my $TransformedFileName=$IdExp1.$IdExp2.$idExp3; return $TransformedFileName; }
    I have not tested it.
    I hope this is what you need.

    Thanks
    SasiKumar
Re: Mass file renaming
by GrandFather (Saint) on Jul 19, 2005 at 22:06 UTC

    Seems you want to break the names into three chunks with the prefix and suffix retaining their original values and the middle chunk incrementing every time a new suffix sequence starts.

    That being the case something like this should work:

    use strict; use warnings; my $prefix; my $midCount; my $lastSuffix; while (<DATA>) { chomp; my $oldName = $_; $prefix = substr $_, 0, 3 if ! defined $prefix; my $suffix = substr $_, -2; ++$midCount if ! defined ($lastSuffix) or $suffix <= $lastSuffix; $lastSuffix = $suffix; my $newName = sprintf ("%03s%06d%02d", $prefix, $midCount, $suffix); print "$oldName -> $newName\n" }

    Perl is Huffman encoded by design.
Re: Mass file renaming
by rruiz (Monk) on Jul 20, 2005 at 07:52 UTC

    Once you have the file name in a var like:

    $filename = 'aa22200010001.png';

    You can use either:

    $filename =~ s/(\d{3})(\d{6})(\d{2})/sprintf("%03d%06d%02d", $1,$2+1,$ +3)/e;

    Or (as pointed by BrowserUK):

    $filename =~ s/(\d{11})/$1 + 100/e;

    Just note that if your file name var contains the path to the file, and one of the directories in the path contains a similar name (ie. eleven consecutive digits, as in: '/tmp/0123456789019/22200010001.png'), you will have to modify the regexp to take it into account and the replacement part will/may not be so simple.

    HTH,
    God bless you
    rruiz

Re: Mass file renaming
by anonymized user 468275 (Curate) on Jul 20, 2005 at 13:04 UTC
    ...all of which boils down to:
    perl -e 'map( rename ($_, $_-9900), glob "222*"));'

    One world, one people

      Unless you're using Perl 5.8.1 or greater, using map in a void context like that is a bad idea. Even on a relatively recent Perl I still think it's harder to follow than the alternative using "for".

      perl -e 'rename ($_, $_-9900) for glob "222*";'
      --
      <http://www.dave.org.uk>

      "The first rule of Perl club is you do not talk about Perl club."
      -- Chip Salzenberg

        I quite agree that your version with for reads better than map. However, having followed the linked discussion as you suggest, I see no justification for going as far as calling it 'bad' to use map in void context and consider that part an overreaction.

        One world, one people