views:

124

answers:

4

I'm trying to move a file but I want to ensure that it exists before I do so. What's the simplest way to do this in Perl?

My code is like this. I looked up the open command, but I am not sure it is the simplest way or not.

if  #Parser.exe exist in directory of Debug
{
    move ("bin/Debug/Parser.exe","Parser.exe");
}
elsif  #Parser.exe exist in directory of Release
{
    move ("bin/Release/Parser.exe","Parser.exe");
}
else
{
    die "Can't find the Parser.exe.";
}

Thank you.

+4  A: 

You can make use of -e file test to check for file existence:

use File::Copy;

if(-e "bin/Debug/parser.exe") {
 copy("bin/Debug/parser.exe","Parser.exe") or die "Copy failed: $!";
} elsif(-e "bin/Release/Parser.exe") {
 copy("bin/Release/parser.exe","Parser.exe") or die "Copy failed: $!"; 
} else {
 die "Can't find the Parser.exe.";
}
codaddict
Thank you too. :-)
Nano HE
+3  A: 

What you need is a file test operator to check if the file exists. Specifically, you need the -e operator which checks if a file exists.

if (-e "bin/Debug/Parser.exe")
{
    move ("bin/Debug/Parser.exe","Parser.exe");
}
elsif (-e "bin/Release/Parser.exe")
    move ("bin/Release/Parser.exe","Parser.exe");
else
{
    die "Can't find the Parser.exe."
}
Nathan Fellman
I prefer to use **move**. Keep the unique Parser.exe. Thanks a lot.
Nano HE
+4  A: 

Personally I don't like the duplication of the file/ path name in these solutions - speaking for myself I suspect I might change accidently it to

  if(-e "pathone....")... { copy("pathtwo...","Parser.exe")

I would do something like

   copy("bin/Debug/parser.exe","Parser.exe")   or 
   copy("bin/Release/parser.exe","Parser.exe") or  
   die "Can't find the Parser.exe.";

Or if that is a bit risque

   copy_parser("bin/Debug")   or 
   copy_parser("bin/Release") or  
   die "Can't find the Parser.exe.";

sub copy_parser {
    my $path = shift ;
    my $source = File::Spec-> catfile ( $path, 'Parser.exe' ) ; 

    if ( -e $source ) {
       copy( $source, "Parser.exe") or die "Copy or $source failed: $!";
       return 1 ;
    }
    return 0 ;
}
justintime
It's a great help for me. THANKS.
Nano HE
+2  A: 

justintime is on the right track when he notes the repetition and seeks to eliminate it. I took the minimization a step farther than he did.

Rather than encapsulate only the copy/move portion of the code, though, it makes sense to remove as all the repetition by encapsulating the list iteration.

I put the subroutine in a module so it can be reused later as needed. This also reduces repeated code.

use SearchMove;

my $found = search_and_move( 
    src  => 'Parser.exe',
    dest => 'Parser.exe',
    dirs => [ 
        "bin/Debug",  
        "bin/Release",
    ],
);

die "Can't find the Parser.exe\n"
    unless defined $found;

print "Found Parser.exe in $found";

In SearchMove.pm

package SearchMove;

use strict; use warnings;

use Exporter 'import';

our @EXPORT_OK = qw( search_and_move );
our @EXPORT = @EXPORT_OK;    

sub search_and_move {
    my %arg = @_;

    croak "No source file"  unless exists $args{src};
    croak "No dest file"    unless exists $args{dest};
    croak "No search paths" unless exists $args{dirs};

    my $got_file;

    for my $dir ( @{$arg{dirs}} ) {

         my $source = "$dir/$arg{src}";

         if( -e $source ) {
             move( $source, $arg{dest} );
             $got_file = $dir;
             last;
         }

    }

    return $got_file;
}

1;

Now you can use search_and_move in many different projects.

daotoad
Hi daotoad, Great thanks for your solution.
Nano HE