Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

File Extension Renaming

by Anonymous Monk
on Jul 05, 2006 at 15:39 UTC ( [id://559366]=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 open a Directory and rename any file that has extension ".log" to ".txt", but my code here isn't working, any help?!

opendir(DIR,"$destinationDirectory") || die "NO SUCH Directory: $desti +nationDirectory"; foreach $zips (readdir DIR){ #while (my $zips = readdir(DIR) ){ $zips=~s/\.log/\.txt/ig; } close(DIR);


Thanks for the Help!

Replies are listed 'Best First'.
Re: File Extension Renaming
by jdtoronto (Prior) on Jul 05, 2006 at 15:45 UTC
Re: File Extension Renaming
by davorg (Chancellor) on Jul 05, 2006 at 15:45 UTC

    Please define what you mean by "my code here isn't working". Exactly what unexpected behaviour are you seeing?

    The code here doesn't actually rename any files. It goes through a list of filenames and performs a substitution on a variable which contains each filename in turn. But it then throws away that value before doing anything useful with it.

    Perhaps you need the "rename" function.

    --
    <http://dave.org.uk>

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

      Sorry, it means that I can't rename the file extension.

        Ok. I see that. Your code isn't renaming the files because you aren't doing anything that would rename the files.

        Each time round your loop, the $zip variable gets the name of one of your files. You then perform a substitution on that variable so that '.log' is changed to '.txt'. But all you've done is to change the value in the variable. That variable doesn't have any connection back to the file that's sitting on your hard disk. In order to rename the file, you need to call a function that asks the operating system to rename the file. And that function (as you've been told) is called rename.

        Is that clearer?

        --
        <http://dave.org.uk>

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

Re: File Extension Renaming
by ciderpunx (Vicar) on Jul 05, 2006 at 15:55 UTC
    You're changing the value of $zips, but not the name of the file. You're maybe after something like:
    #!/usr/bin/perl $dir = "./test"; opendir(DIR,$dir) || die "NO SUCH Directory: $dir\n$!"; foreach $zips (readdir DIR){ $new_name = $zips; $new_name =~ s/\.log/\.txt/ig; rename "$dir/$zips","$dir/$new_name" || die("Can't rename $zips\n$ +!"); } close(DIR);
    HTH
      In your rename ... || die, the || binds too tightly: it binds to the "$dir/$new_name" string, not to the return value of rename(). Either use rename(...) || die or rename ... or die.

      Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
      How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
      Should make that
      $new_name =~ s/\.log/\.txt/ig or next;
      so that it skips non-.log files .. otherwise the s/// will fail and rename will have identical OLDNAME and NEWNAME arguments.
      Changing your code to this will avoid the name collision problem - rename will overwrite a duplicate named file.
      #!/usr/bin/perl $dir = "./test"; opendir(DIR,$dir) || die "NO SUCH Directory: $dir\n$!"; foreach $zips (readdir DIR){ $new_name = $zips; $new_name =~ s/\.log/\.txt/ig; rename ("$dir/$zips","$dir/$new_name") unless ($zips eq $new_name) +; } close(DIR);
      jdtoronto
Re: File Extension Renaming
by swampyankee (Parson) on Jul 05, 2006 at 16:27 UTC

    You're changing the value of $zips but that doesn't change the name of the file any more than writing "deposit $4_000_000_000" in your checkbook will add money to your checking account; you've got to use rename to tell the operating system to rename the file (alas, I don't know the Perl function to add money to my checking account).

    Try something like this:

    opendir(DIR,$destinationdirectory) or die "Could not open $destination +directory because $!\n"; foreach (my $zips = readdir(DIR)){ ($txt = $zips) =~ s/\.log$/.txt/i; unless(rename($zips, $txt)){ warn "could not rename $zips to $txt because $!\n"; next; } }
    Warning Code was NOT tested.


    minor update

    In addition to the advice about collisions, you should probably check permissions on the directory holding the files to be renamed.

    emc

    e(π√−1) = −1
Re: File Extension Renaming
by davidrw (Prior) on Jul 05, 2006 at 17:09 UTC
    DOS solution:
    ren *.log *.txt
    bash solution:
    for f in /tmp/*.log ; do mv $f ${f%%.*}.txt; done
    File::Find::Rule solution:
    my @files = File::Find::Rule->file()->name('*.log')->maxdepth(1)->in($ +destinationDirectory); foreach my $src ( @files ){ my $dest = $src; $dest =~ s/[^.]+$/txt/; rename $src, $dest; }
Re: File Extension Renaming
by dimar (Curate) on Jul 05, 2006 at 17:05 UTC

    Also note, to prevent possible errors and data loss, you should make sure your renaming operation does not introduce unintended naming collisions.

    For example, if your directory already has a file called "foobar.txt", what does your program do when it encounters the file "foobar.log"? Some of the code listed above handles this issue, but it does well to expressly understand this and figure out how you want to handle it.

    =oQDlNWYsBHI5JXZ2VGIulGIlJXYgQkUPxEIlhGdgY2bgMXZ5VGIlhGV

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (11)
As of 2024-04-23 08:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found