Abhynav has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks, I want to iterate over files in a particular directory and rename them according to custom logic. Now my question is how do I iterate over the various files in order to rename them. I tried using File::Find module, but it seems it locks out file while iterating over them and the program throws an error saying that the file is being used by some other program. What is the common practise of acheiving the same? Thanks, Abhinav

Replies are listed 'Best First'.
Re: Mass File Renaming
by eyepopslikeamosquito (Archbishop) on Sep 09, 2005 at 07:05 UTC

    You should post the code you have tried and describe the precise error message you got when you ran it.

    For some general solutions to renaming files, see Larry's famous rename script and Unix rename faq (a version of Larry's script is given at the end). It's also discussed in Perl Cookbook, recipe 9.9.

      See also rename 0.3 - now with two extra cupholders, my personal big overhaul of that script.

      Which reminds me I need to clean up the current, much further developed version and post it sometime…

      Makeshifts last the longest.

      Update: Err... this is an old node... I got confused by Mass file renaming. It looks like someone posted under this node than started a new thread with the same title. Blah...

      I'm not sure TimToady's script (or Aristotle's version which I like and use quite a lot) is the right solution in this case given that the OP claimed he was extracting info from the file itself.

      -sauoq
      "My two cents aren't worth a dime.";
      
Re: Mass File Renaming
by marto (Cardinal) on Sep 09, 2005 at 07:05 UTC
Re: Mass File Renaming
by zentara (Cardinal) on Sep 09, 2005 at 11:58 UTC
    Here is a powerful little renamer, but be careful, it can do some unexpected renaming unless you are careful.
    #!/usr/bin/perl #usage: zrn 'oldext' 'newext' 'topdir' #include the the . for extensions, otherwise anystring will change in +the filenames #if you want to append .bak to files, use $ for 'oldext' ex: zrn $ .ba +k . #the ext is always applied to the end of the filename #to strip extensions: zrn .bak '' . use strict; use File::Find; my ($in,$out,$path) = @ARGV; my $timestamp = localtime(); $timestamp =~ s/ /|/g; if (@ARGV <2){die "Usage zrn 'oldext' 'newext' 'top directory' -> '.' +is good examples: zrn .bak .old . zrn \$ .bak . zrn .bak '' .\n"}; finddepth (\&wanted,$path); sub wanted { my $old = $_; return unless -f; #-d for dir ops or comment out for both $_ =~ s/$in$/$out/; #do ops here if ($_ eq $old){return}; if (-e $_) {$_ = $_.$timestamp; warn("timestamping $_ to avoid overwri +ting existing file")}; rename $old, $_ or warn "Cannot rename $old to $_ in $File::Find::dir: + $!"; };

    I'm not really a human, but I play one on earth. flash japh
Re: Mass File Renaming
by bluto (Curate) on Sep 09, 2005 at 15:39 UTC
    I'm unfamilar with File::Find locking out files (i.e. Is this Windows?), so perhaps that's something to figure out. In any case here's a low tech solution is to post process them. For example, use File::Find to find the files and then append them to an array (or write them to a file if you have huge numbers of them). Once File::Find completes, then rename the files. Of course you run a greater risk of a file being changed between the time that you find them and the time you rename them, so YMMV.
Re: Mass File Renaming
by chester (Hermit) on Sep 09, 2005 at 17:35 UTC
    Depending how complex your logic is, if all the files are in the same directory you can always do something like

    ls | perl -nle 'print $_'

    Replacing the print with something useful. I use this all the time to rename files.

Re: Mass File Renaming
by Anonymous Monk on Nov 07, 2005 at 12:28 UTC
    Hi, my first post here so apologies as required in advance... I've run into a similar problem, using: my @files=<c:/Storage/*.csv>; #Reads all csv files foreach(@files){ $newname=(extract some data from the file here) $success=rename $oldname,$newname; } The error message I get is 'permission denied'. If I have "old.txt" file in the same dir and execute a simple $success=rename "old.txt","new.txt"; then it works ok. If I change: @files=<c:/Storage/*.csv>; to @files=<c:/Storage/*.txt>; then it doesn't. Confused, please help.