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

Hi, I'm very new to perl and am trying to write a script that will basically say "look in a folder and if the file that is in that folder is the same as any of the files in a second folder then rename the first file by adding an "_1". There will always only be one file in the first folder but can be many in the second folder. I wrote the code below but it doesn't seem to do anything. Help would be appreciated. Thanks!

#! /usr/bin/perl use diagnostics; $tempdir="c:/Temp/OneFile"; opendir(TMP, $tempdir) || die; @onefile= readdir(TMP); closedir(TMP); $permdir="c:/Support/Files"; opendir(PMD, $permdir) || die; @allfiles= readdir(PMD); closedir(PMD); our @onefile_1; foreach $file (@allfiles) { if ($file eq "@onefile") { rename("$onefile", "@onefile_1.txt"); } } exit(0); __END__ :endofperl

Replies are listed 'Best First'.
Re: comparing folders
by toolic (Bishop) on Jul 28, 2010 at 19:03 UTC
    if ($file eq "@onefile")
    It probably doesn't work because those double quotes will interpolate all the elements of the array into a single string (with a single space between each element). Since readdir returns all of a directory's contents, @onefile probably has 3 elements: the file you expect to be there and the special dot directories (. and ..). You should filter the output with grep -f, or use nested for loops (one for each array), or load the first files into a hash.

    Inspect the contents of your array using Data::Dumper (tip #4 from the Basic debugging checklist):

    use Data::Dumper; print Dumper(\@onefile);

    You should be able to adapt the solution to a similar problem: Re: Comparing Directories and copy files

    rename("$onefile", "@onefile_1.txt");
    To append _1, you really want something like this:
    rename $onefile, $onefile . '_1.txt' or die "Can not rename: $!";
      Thanks toolic! I didn't realize that "" will interpolate the elements into a string.
Re: comparing folders
by jwkrahn (Abbot) on Jul 28, 2010 at 20:30 UTC

    When you say "a file is the same" do you mean the file name or the file contents?

    This will compare based on the file name (UNTESTED):

    #!/usr/bin/perl use warnings; use strict; my $tempdir = 'c:/Temp/OneFile'; my $permdir = 'c:/Support/Files'; opendir my $TMP, $tempdir or die "Cannot opendir '$tempdir' $!"; my @onefile = grep -f "$tempdir/$_", readdir $TMP; closedir $TMP; if ( @onefile > 1 ) { die "Error: more than one file in $tempdir\n"; } if ( -f "$permdir/$onefile[0]" ) { rename "$tempdir/$onefile[0]", "$tempdir/$onefile[0]_1.txt" or die + "Cannot rename '$tempdir/$onefile[0]' to '$tempdir/$onefile[0]_1.txt +' $!"; } exit 0; __END__
      Exactly what I needed it to do, thanks jwkrahn!
Re: comparing folders
by morgon (Priest) on Jul 28, 2010 at 19:28 UTC
    I think you want to test with "$file eq "@onefile" whether $file is contained in the array @onefile.

    This is the wrong syntax.

    What I would do is using a hash:

    my %onefile= map { $_ => 1 } readdir(TMP); # Now every file in TMP is a key in the hash ... # and later we check like this: foreach $file (@allfiles) { if ($onefile{$file}) ...
      That's exactly what I was trying to do. Thanks for the syntax help morgon!