Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

rename files

by Anonymous Monk
on Aug 08, 2005 at 13:29 UTC ( #481869=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I am having a few difficulties renaming files. In directory /.temp_gif i have files 1.gif, 3.gif etc. I would like to rename these 399.GIF, 401.GIF i.e. increment the value by 398 and capatalize the gif. I have chmod the files but unable to use File::copy, not compliled and i dont have admin password.
opendir (DH, "/temp_gif") or die "unable $!"; foreach (readdir DH) { ($number, $gif) = split (/\./); print "$number\n"; $numbers_replace =$number+338; $gif_replace = "GIF"; rename ($number.gif, $numbers_replace.GIF);

Replies are listed 'Best First'.
Re: rename files
by talexb (Canon) on Aug 08, 2005 at 13:44 UTC

    How about adding or die "Unable to rename $number.gif to $numbers_replace.GIF: $!" to your last line so we can find out why it's failing?

    Once you know what the problem is, you can address that.

    Alex / talexb / Toronto

    "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

      the error print unable to find file. the file does exist with correct file permission

        That rather backs up Fletch's theory. You need to put the directory name back onto the filenames before trying to rename them.


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

        OK, now we're getting somewhere. Is it unable to find the source file, the first file? I expect that's the case, since you're trying to create the destination file.

        Are you checking that the file exists as the same user? That is, are you running the script from a prompt or is it a CGI or something run from cron?

        The reason I'm asking is that the script is not able to see the file, while you are. The script isn't lying -- it really can't see the file. If you can see the file, then you must be looking at a different system or running with different privileges.

        Alex / talexb / Toronto

        "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

Re: rename files
by izut (Chaplain) on Aug 08, 2005 at 15:12 UTC
    The problem is the foreach passes to block just the filename (1.gif, 3.gif). You should concatenate the path (/temp_gif) and the filename (3.gif) when rename()ing.
    $dir = "/temp_gif"; opendir(DH, $dir) or die $!; foreach (readdir DH) { next if /^\.?\.$/; ($number, $gif) = split /\./; print "$number\n"; $numbers_replace = int($number) + 338; rename("$dir/$_", "$dir/$numbers_replace.GIF") or warn $!; }

    Igor S. Lopes - izut
    surrender to perl. your code, your rules.
Re: rename files
by srdst13 (Pilgrim) on Aug 08, 2005 at 13:34 UTC


    Note the quotes. Does that do it?


      Probably not since, aside from not checking the return status from rename, the pathnames still aren't being adjusted relative to the base directory they passed opendir.

      We're looking for people in ATL

        The proof of this (probably accurate) issue could also be being hidden if '/temp_gif' is not a valid mountpoint -- it seems rather plausible, though not yet proven, that './temp_gif' is what was wanted.

        One world, one people

      i also tried that with no success
Re: rename files
by SimonClinch (Deacon) on Aug 08, 2005 at 13:43 UTC
    The most pertinent issues are:

    (1) split has no default second argument, so the $_ needs to be explicit.

    (1) at the least under unix, you could get an error trying to rename . and .. (the current and parent directories). To avoid that, replace the readdir with

    grep !/^\./, readdir
    (2) but, just in case there are yet more files in the directory that you don't want to rename, you might consider instead:
    grep /^\d+\.gif/, readdir

    (3) the '.' operator in the arguments to rename will not produce a literal '.' as has already been hinted at.


    (4) it is possible but suspicious that you expect to have a mount point at '/temp_gif' ... should this not be './temp_gif'?

    (5) if so, then when that is corrected, the fix suggested by others of putting the relative or full path in front of the arguments to rename will become able to function.

    One world, one people

      (1) split has no default second argument, so the $_ needs to be explicit.

      Erm . . .

      split /PATTERN/,EXPR,LIMIT split /PATTERN/,EXPR split /PATTERN/ split Splits a string into a list of strings and returns [ . . . ] + If EXPR is omitted, splits the $_ string.

      We're looking for people in ATL

Re: rename files
by chester (Hermit) on Aug 08, 2005 at 16:08 UTC
    readdir is not my friend. If you use File::Find, you don't have to mess with relative vs. absolute pathnames. You can use $File::Find::name, which is a complete pathname. You don't have to worry about '..' and '.'. Etc. etc. Quite untested:

    use File::Find; find(\&wanted, '/temp_gif'); sub wanted { return unless /^\d+\.gif$/i; (my $new_name = $File::Find::name) =~ s/(\d+)\.gif$/($1+398) . 'GIF'/ei; rename($File::Find::name, $new_name) or die $!; }
Re: rename files
by trammell (Priest) on Aug 08, 2005 at 14:56 UTC
    Untested, using the command-line 'rename' utility:
    % rename 's/(\d)\.gif/$1+398 . ".GIF"/e' *.gif
    Update: minor fix to filename suffix.

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (5)
As of 2018-02-24 20:19 GMT
Find Nodes?
    Voting Booth?
    When it is dark outside I am happiest to see ...

    Results (310 votes). Check out past polls.