in reply to Re: Renaming files in directory
in thread Renaming files in directory

If you just want to rename files, then I would suggest that you just use the rename built-in function of Perl, rather than using the File::Copy module.

why? "If possible, move() will simply rename the file."

Replies are listed 'Best First'.
Re^3: Renaming files in directory
by Laurent_R (Canon) on Jan 06, 2018 at 09:31 UTC
    Sure, the move function the File::Copy module will rename the file, it is just a bit simpler to use a builtin function (such as rename) when it exists.
      Thank you for your anwers. I have so much on my mind right now, that I have to get back to it somewhat later.
      But thank you for your answers. I appreciate it.
      I have looked at your posts and I have tried the code of haukex and it works, but I don't really understand the code. Can you look again at the code that I have written?
      #!bin/perl use strict; use warnings; use File::Spec; my $directory = '/home/porter/Videos/blue/'; opendir(DIR,$directory); my @oldfiles = File::Spec->no_upwards( readdir DIR ); closedir(DIR); my @newfiles = qw(Alfa Bèta Gamma Delta Epsilon Zèta Èta Thèta Iota K +appa Lambda Mu Nu Ksi Omikron); my $a = @oldfiles; my $b = @newfiles; if ( $a ne $b ) { print "the numbers are not equal\n" and die; } for (my $i = 0; $i < $a; $i++) { rename $oldfiles[$i],$newfiles[$i]; }
      The programs exits with code 0 so that is okay, but it doesn't do what it is supposed to do.
        doesn't do what it is supposed to do.

        So, what does it instead?


        I see a few problems in the code:

        #!bin/perl

        No problem for Perl. In fact, Perl does not even need this line. But your operating system may need it. The path to the perl executable should be absolute, not relative, so a leading slash is missing between #! and bin/perl. And the path looks wrong, I've never seen Perl installed to /bin/perl. The system perl is usually /usr/bin/perl, administrators tend to install a (probably newer) perl to /usr/local/bin/perl. Sometimes, the latter is just a symlink to the former.

        opendir(DIR,$directory);

        No error check. Use opendir(DIR,$directory) or die "Could not open directory $directory: $!";

        Also, bareword handle instead of scalar. This does not hurt, but is considered bad style. See the example in readdir.

        my $a = @oldfiles; my $b = @newfiles; if ( $a ne $b ) { print "the numbers are not equal\n" and die; }

        Don't use variables named $a or $b, they are reserved for sort and because of this, they are excluded from some of Perl's error checks.

        You are comparing numbers using a string compare operator (ne). This may accidentally work, but you really want to use a numeric operator (!=). See also Re^3: xs modifying passed value.

        You are writing an error message to STDOUT, then let die write a non-helpful default error message to STDERR. Error messages don't belong to STDOUT. Just pass the error message to die.

        If print fails and therefore returns false, die won't be called and your code will continue even if you have detected a fatal error. Again, just pass the error message to die and get rid of print and and here.

        The error message is not very useful. What numbers? And why should they be equal? A user should not be forced to read the source code to understand error messages. Try die "Found $a files in $directory, but expected $b. Died"; to see the difference.

        for (my $i = 0; $i < $a; $i++) { rename $oldfiles[$i],$newfiles[$i]; }

        Rename lacks an error check. Like for opendir, append or die with a reasonable error message: rename $oldfiles[$i],$newfiles[$i] or die "Could not rename $oldfiles[$i] to $newfiles[$i]: $!";.


        If you don't want to manually check each and every I/O operation for errors, add the line use autodie; to your code after having read autodie.

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)