Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Filename change with regular expression

by Anonymous Monk
on Aug 09, 2013 at 19:07 UTC ( [id://1048824]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks!

I am trying to change some things on file names I have in my project but the last one is a kill; replace the last part of the file name only if it ends with "_00001". I am trying to do this in one regular expression line, can I add some sort of conditional to the regexp to do this? here is a code sample:
my $rd = int( rand(100000)) + 999999; my $filename = "XYZ12345_X05_20110805_9999999_00001.TXT"; #my $filename = "XYZ12345_X05_20110805_9999999.TXT"; #add dash between $3 and $4 to the .txt before processing them::: #pad $2 with 0s #replace the end of the file with a randon number if the filename ends + with _00001 (my $xrenamed = $filename) =~s/(^\w{3})(\d{5,7})(_\w{1})(\w{1,2}_)(\d{ +8}\_)(.*)/$1.sprintf("%07d",$2).$3."-".$4.$5.$rd.".txt"/ie; # print "\n\nFILE = *1- $1 * 2 - $2* 3 - $3* 4 - $4* 5 - $5* 6 - $6* - $ +xrenamed\n\n";

Replies are listed 'Best First'.
Re: Filename change with regular expression
by McA (Priest) on Aug 09, 2013 at 19:30 UTC

    I'm not sure whether you mean that:

    my $rd = int( rand(100000)) + 999999; $filename =~ s/_00001\./_$rd./;

    Best regards
    McA

      That just generates a randon numbers with 7 digits( any better way?). I can get whant I need using an "IF" but I am trying to do all in one regular expression.
      #not using strict and -w for this example only my $rd = int( rand(100000)) + 999999; my @files = qw( XYZ12345_X05_20110805_8999999_00001.TXT XYZ12345_X05_2 +0110805_9999999.TXT); #add dash between $3 and $4 to the .txt before processing them::: #pad $2 with 0s #replace the end of the file with a randon number if the filename ends + with _00001 foreach my $f(@files) { if($f=~/(^\w{3})(\d{5,7})(_\w{1})(\w{1,2}_)(\d{8}\_)(\d{7}_\d{5}\.\w +{3})/i) { (my $xrenamed = $f) =~s/(^\w{3})(\d{5,7})(_\w{1})(\w{1,2}_)(\d{8}\ +_)(\d{7}_\d{5}\.\w{3})/$1.sprintf("%07d",$2).$3."-".$4.$5.$rd.".txt"/ +ie; print "\n\n $xrenamed\n\n"; }else{ (my $xrenamed = $f) =~s/(^\w{3})(\d{5,7})(_\w{1})(\w{1,2}_)(\d{8 +}\_)(\d{7}_\.\w{3})/$1.sprintf("%07d",$2).$3."-".$4.$5.$6/ie; print "\n\n $xrenamed\n\n"; } }
      Thanks!
        but I am trying to do all in one regular expression.

        Why? Other than decreasing readability and maintainability of the code, I see no purpose of having it as a single regular expression.

        Jason L. Froebe

        Blog, Tech Blog

        Hi,

        I read you initial question again and again and I don't understand your answer. Probably to clarify here a little more code:

        use strict; use warnings; use 5.010; my @filenames =('XYZ12345_X05_20110805_9999999.TXT', 'XYZ12345_X05_201 +10805_9999999_00001.TXT'); for my $filename (@filenames) { my $rd = int( rand(100000)) + 999999; say "unchanged_filename: $filename"; $filename =~ s/_00001\./_$rd./; say "changed_filename: $filename"; }

        So, what are my assumptions: You do only have one '.' in your filename seperating the extention 'TXT' from the part you called filename. With this assumption there is exactly one "reference" point in the regex and that is the point separating the extention. That means, if and only if a substring of the format _00001 preceeds the point, therefor is at the end of your "filename" I do a substitution of that part with a random number you provided in your example.

        Have I understood your problem totally wrong?

        Best regards
        McA

Re: Filename change with regular expression
by kcott (Archbishop) on Aug 10, 2013 at 10:22 UTC

    You appear to be bogged down matching all sorts of things that you're not interested in. You only want to match the "00001" in "XYZ12345_X05_20110805_9999999_00001.TXT". This regex does that:

    /(?<=_)00001(?=[.]\w+$)/

    Then, you want to replace that with a random number. Your sprintf format indicates: seven digits, right-aligned, zero-padded. As the "%d" in the sprintf format already indicates an integer, you don't need to use int. Assuming zero is not a valid random number for your requirements, the range is "0000001" to "9999999". You can get that range with:

    rand(9999999)+1

    So, putting all that together, we get:

    s/(?<=_)00001(?=[.]\w+$)/sprintf "%07d" => rand(9999999)+1/e

    [Note: your "int( rand(100000)) + 999999" will produce this range: "0999999" to "1099998". I'm guessing that's not really what you want; however, if you want some different from the range I suggested, see rand for the values it returns and adjust accordingly.]

    I ran some tests (which included edge cases) with this code:

    $ perl -Mstrict -Mwarnings -le ' my @test_filenames = qw{ XYZ12345_X05_20110805_9999999_00000.TXT XYZ12345_X05_20110805_9999999_00001.TXT XYZ12345_X05_20110805_9999999_00002.TXT XYZ12345_X05_20110805_9999999_00001x.TXT XYZ12345_X05_20110805_00001_00001.TXT XYZ12345_X05_20110805_00001_00001xxx.TXT }; for (@test_filenames) { s/(?<=_)00001(?=[.]\w+$)/sprintf "%07d" => rand(9999999)+1/e; print; } '

    Here's one sample output:

    XYZ12345_X05_20110805_9999999_00000.TXT XYZ12345_X05_20110805_9999999_1656320.TXT XYZ12345_X05_20110805_9999999_00002.TXT XYZ12345_X05_20110805_9999999_00001x.TXT XYZ12345_X05_20110805_00001_0901076.TXT XYZ12345_X05_20110805_00001_00001xxx.TXT

    -- Ken

      It's all good, but the idea is to only do the replacement with the random numbers if the file names end in _00001, then remove this part and replace the 9999999 with the random numbers, the other changes to the files like adding the "-" and pad with 0 if less than 7 digits are for all files.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1048824]
Approved by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (3)
As of 2024-04-18 02:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found