Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Re: Changing filename extensions

by Fletch (Bishop)
on Nov 16, 2021 at 03:45 UTC ( [id://11138863]=note: print w/replies, xml ) Need Help??


in reply to filenames

Always check the return value from system calls like rename; you'd see that it failed. The readdir returns names of files in $dir but they're not prefixed with it so your rename("$name.$old","$name.$new") is trying to rename files in the directory you ran from not the one you named in $dir (you'd need to use "$dir/$name.$old" instead).

You might also check out something like Path::Tiny for another interface which might be easier to work with.

Edit: And just for clarity, by checking the return value I mean when you call things like opendir or rename that interact with the OS you should check their return value and print a meaningful error message when things go wrong. E.g.:

opendir( my $dirhandle, $dir ) or die "Can't opendir directory '$dir': + $!\n"; rename( "$dir/$name.$old", "$dir/$name.$new" ) or warn "Problem renaming '$dir/$name.$old' to '$dir/$name.$new': $! +\n";

The cake is a lie.
The cake is a lie.
The cake is a lie.

Replies are listed 'Best First'.
Re^2: Changing filename extensions
by supernova95 (Initiate) on Nov 16, 2021 at 04:03 UTC
    Okay so I have it working now! But I have one more question, is there a way to get my code to also account for files in subdirectories of the directory?

      This may work (UNTESTED):

      #!/usr/bin/perl use strict; use warnings; use File::Find; @ARGV == 3 or die "usage: $0 DIR OLD_EXT NEW_EXT\n"; my $dir = $ARGV[ 0 ]; my $old = $ARGV[ 1 ]; my $new = $ARGV[ 2 ]; my @list; find sub { push @list, $File::Find::name if -f && /\.\Q$old\E\z/; }, $dir; foreach my $old_name ( @list ) { my $new_name = $old_name =~ s/\.\Q$old\E\z/.$new/r; rename $old_name, $new_name or die "Cannot rename '$old_name' beca +use: $!"; }

      You could use the -d test to look for entries that are themselves directories and then recurse down into them but at that point you'd have started down the path of reimplementing what something like Path::Tiny (or File::Find, or File::Find::Rule, or Path::Iterator::Rule, or . . .) could do for you off the shelf so you'd be better of using that to begin with.

      ## presuming your sample vars for dir, old, new ## Somewhat untested, but . . . use Path::Tiny qw( path ); my $iter = path( $dir )->iterator( { recurse => 1 } ); while( my $path = $iter->() ) { next unless $path->is_file and $path =~ m{\. $old $}x; my $new_path = $path->basename( $old ) . ".$new"; unless( my $ret = $path->move( $new_path ) ) { warn "Problem moving '$path': $ret\n"; } }

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (2)
As of 2024-04-25 19:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found