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

Hello Monks

I am looking for generic way to implement the following task
Suggest me some ideas

I have a directory say c:\test under which there are some files with names as
ABCTEST_062506.DAT XYZTEST_062506.DAT ABCTEST_062406.DAT XYZTEST_062506.DAT ABCTEST_062406.DAT XYZTEST_062506.DAT ABCTEST_062406.DAT XYZTEST_062506.DAT
The filenames which start with ABC has to be renamed with
ABCD and filenames start with XYZ should be renamed with XYZD...
I am scanning the directory for files
sub scanDir() { $check ="ABCD" # this value will come from an array $base_dir = $_[0]; opendir(DIR, $base_dir) || die "Error: could not open input direct +ory $base_dir"; @current_dir = readdir(DIR); chomp(@current_dir); foreach $current_dirs (@current_dir) { $file_name = $current_dirs; $var = substr($file_name, 0, 3); $newvar = substr($file_name,3); if($var eq $check){ $newFileName = $check . $newvar; } } closedir(DIR); }

Is this approach correct way

Note: I updated the code there were some mistakes
The idea is to make it generic if suppose some new file names
comes and all we have to specify the new filename and code should work
The original filename will remain same when the file is
copied or moved it will be renamed
Thanks in advance

Sridhar

Replies are listed 'Best First'.
Re: FileName Change
by davorg (Chancellor) on Aug 21, 2006 at 15:22 UTC

    Is this the actual code that you're trying to use? Because there seem to be a few problems with it.

    • You use "opendir", but never read from the directory with "readdir"
    • You use an array called @current_dir which is never populated (I think you probably need to populate it using a call to "readdir")
    • You're using an operator (-eq) which doesn't exist in Perl. I think you want 'eq' instead
    • Your new file name doesn't include D
    • You don't actually rename the file at any point. You probably need to call the "rename" function at some point

    Other than that, you're not defining any of your variables (with "my") which implies that you don't have "use strict" in your program. Programming something like this without "use strict" or "use warnings" is just silly. Why write code without all the help you can get from the compiler?

    --
    <http://dave.org.uk>

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

Re: FileName Change
by Fletch (Bishop) on Aug 21, 2006 at 15:21 UTC

    Well, aside from never actually renameing the file nor inserting the extra "D" into the new filename yes that's on the right track.

Re: FileName Change
by un-chomp (Scribe) on Aug 21, 2006 at 16:31 UTC
    This may, or may not be, what you want:
    #!/usr/bin/perl use strict; use warnings; use File::Basename; use File::Find::Rule; my @files = File::Find::Rule->file() ->in( 'c:/test/'); foreach my $file ( @files ) { my ( $old_name, $path ) = File::Basename::fileparse( $file ); my $new_name = $old_name; $new_name =~ s/^ABC/ABCD/; $new_name =~ s/^XYZ/XYZD/; next if $new_name eq $old_name; rename( $path . $old_name, $path . $new_name ) or die "Renaming $old_name to $new_name: $!"; # or copy, as per your update # require File::Copy; # File::Copy::copy( $path . $old_name, $path . $new_name ) # or die "Renaming $old_name to $new_name: $!"; }
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: FileName Change
by blazar (Canon) on Aug 21, 2006 at 17:03 UTC
    $check ="ABCD" # this value will come from an array # ... $var = substr($file_name, 0, 3); # ... if($var eq $check){

    I don't think the condition could ever be possibly satisfied. Also, I wouldn't use non-descriptive variable names like $var and $newvar.

    Is this approach correct way

    More or less so. But your requirements are slightly sloppy and in particular there's a discrepancy between the description of the task and what the code more or less does, but if I understand them correctly, then I'd do something along the lines of:

    sub scandir { my $dir=shift; my $test=join '|', map quotemeta, @_; chdir $dir; for (glob '*') { next unless /^($test)(.*)/; my $new="$1D$2"; print "`$_' => `$new'\n"; if (-e $new) { warn "Warning: `$new' exists\n"; # or do something more complex... next; } else { rename $_, $new or die "Can't rename to `$new': $!\n"; } } }