Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

I cannot create backup copy during file name change

by rnaeye (Pilgrim)
on Jul 24, 2012 at 15:03 UTC ( #983433=perlquestion: print w/replies, xml ) Need Help??
rnaeye has asked for the wisdom of the Perl Monks concerning the following question:

Hi! I am trying to change file names in a directory. My code (I cannot remember where I found the original script) is as below:
#!/usr/bin/perl use warnings; use strict; use 5.010; foreach my $file (glob "*.txt") { my $newfile = $file; $newfile =~ s/_oldname_/_newname_/g; if (-e $newfile) { warn "can't rename $file to $newfile: $newfile exists\n"; } elsif (rename $file, $newfile) { } else { warn "rename $file to $newfile failed: $!\n"; } } exit;
This works fine. However, I want to create a backup copy of the original files, in case something goes wrong. I have tried to insert  $^I = ".bak"; at the beginning of the script, but did not work. I must be doing something wrong. Can you please help? Thank you.

Replies are listed 'Best First'.
Re: I cannot create backup copy during file name change
by ww (Archbishop) on Jul 24, 2012 at 16:16 UTC
    The following are just a few elements that trouble my understanding:
    • Since you're globbing "*.txt", you'll never be trying to work on a file called _oldname_ so -- as written (or compressed?) the left side of the regex won't match, making Ln 9 an effective no-op (but one that eats CPU, nonetheless).
    • Since you're globbing "*.txt" and you show no mechanism for revising the values in the regex as you cycle thru your globbed files, the assertion that this script "works fine" seems highly suspect.

    Update: removed stupid comment; added below para on use of rename

    Update2: jethro holds -- with good reason, ++ -- that the 'stupid remark' is the observation that _oldname_ can't match. He's right; I should have allowed for cases in the sort of format OP has now described, below; however, OP's use of glob "*.txt" would never find the .pdf files asserted in Re^2: I cannot create backup copy during file name change.
    FTR, the point was not to make OP look foolish; rather, it is that one should cut'n'paste (double-checked) code into PM nodes, to avoid such goofs, rather than risk the hazards of retyping something that already exists in digital form.
    (...and, BTW, the remark removed was even stupider)

    Also, perldoc -f rename tells us

            Changes the name of a file; an existing file NEWNAME will be
            clobbered. Returns true for success, false otherwise.
            Behavior of this function varies wildly depending on your system
            implementation. For example, it will usually not work across...
    which is (IMO) very nearly a deprecation message.

      I think "bla_oldname_bla.txt" would match the regex quite well

      Hi ww ;

      My files are named as below:


      , and I wanted to change them to something as below:


      My intention was to change the text between underscores (_ _), but not touch the rest of the file name.

        And how does glob "*.txt" find files with a "pdf" extension?
Re: I cannot create backup copy during file name change
by tobyink (Abbot) on Jul 24, 2012 at 15:14 UTC

    That's not what $^I = ".bak" does. It is used in conjunction with @ARGV and the diamond operator.

    If you want to create a backup copy of the file use:

    system cp => $old_filename, $backup_filename;

    (Or File::Copy for better cross-platform support.)

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: I cannot create backup copy during file name change
by Marshall (Abbot) on Jul 25, 2012 at 04:50 UTC
    A "rename" or "move to another directory" is normally a very efficient file system operation. It will not normally "destroy" the source until the "destination' has been created - this is basically a modification of a directory entry - no actual file bits on the disk get changed, just "pointers" to those bits.
    #!/usr/bin/perl -w use strict; my $newdir ="something"; foreach my $file (glob "*.txt") { rename $file, "$newdir/$file" or warn "rename $file to $newfile failed: $!\n"; } # $file will still exist if rename fails
    There is no need to make a back-up of a file before you rename it ("move" it to another directory). There are differences between copy and mv but basically it will work or it will not. If not, the original file is left intact.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://983433]
Approved by toolic
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (7)
As of 2018-05-21 12:10 GMT
Find Nodes?
    Voting Booth?