Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

question regarding File::Copy, and hashes that contain file paths

by Leetsauce (Novice)
on Dec 12, 2015 at 15:48 UTC ( #1150117=perlquestion: print w/replies, xml ) Need Help??

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

#!/usr/bin/perl # PERL MODULES USED use DBI; use DBD::ODBC; use DBD::File; use Time::localtime; use Time::HiRes; use File::Path; use File::Copy; use File::Basename qw( fileparse ); use File::Path qw( make_path ); use File::Spec; use File::Find; use FileHandle; use File::Slurp; use File::PerlMove; use Archive::Zip; print "Modules have been initialized.\n"; # CONFIG HASH my %compHash = ("e:/pervasive/staging/summit/C01" => "e:/pervasive/test/APEX012015 +/C01", "e:/pervasive/staging/summit/C02" => "e:/pervasive/test/APEX022015 +/C02", "e:/pervasive/staging/summit/C03" => "e:/pervasive/test/APEX032015 +/C03", "e:/pervasive/staging/summit/C04" => "e:/pervasive/test/APEX042015 +/C04", "e:/pervasive/staging/summit/C05" => "e:/pervasive/test/APEX052015 +/C05", "e:/pervasive/staging/summit/C06" => "e:/pervasive/test/APEX062015 +/C06", "e:/pervasive/staging/summit/C07" => "e:/pervasive/test/APEX072015 +/C07", "e:/pervasive/staging/summit/C08" => "e:/pervasive/test/APEX082015 +/C08", "e:/pervasive/staging/summit/C30" => "e:/pervasive/test/APEX302015 +/C30", "e:/pervasive/staging/summit/C40" => "e:/pervasive/test/APEX402015 +/C40", "e:/pervasive/staging/summit/C41" => "e:/pervasive/test/APEX412015 +/C41", "e:/pervasive/staging/summit/C42" => "e:/pervasive/test/APEX422015 +/C42", "e:/pervasive/staging/summit/C43" => "e:/pervasive/test/APEX432015 +/C43", "e:/pervasive/staging/summit/C44" => "e:/pervasive/test/APEX442015 +/C44", "e:/pervasive/staging/summit/C50" => "e:/pervasive/test/APEX502015 +/C50", "e:/pervasive/staging/summit/C80" => "e:/pervasive/test/APEX802015 +/C80", "e:/pervasive/staging/summit/C85" => "e:/pervasive/test/APEX852015 +/C85", "e:/pervasive/staging/summit/C99" => "e:/pervasive/test/APEX992015 +/C99", "e:/pervasive/staging/summit/C01-2015" => "e:/pervasive/test/APEX0 +12015/CSW", "e:/pervasive/staging/summit/C02-2015" => "e:/pervasive/test/APEX0 +22015/CSW", "e:/pervasive/staging/summit/C03-2015" => "e:/pervasive/test/APEX0 +32015/CSW", "e:/pervasive/staging/summit/C04-2015" => "e:/pervasive/test/APEX0 +42015/CSW", "e:/pervasive/staging/summit/C05-2015" => "e:/pervasive/test/APEX0 +52015/CSW", "e:/pervasive/staging/summit/C06-2015" => "e:/pervasive/test/APEX0 +62015/CSW", "e:/pervasive/staging/summit/C07-2015" => "e:/pervasive/test/APEX0 +72015/CSW", "e:/pervasive/staging/summit/C08-2015" => "e:/pervasive/test/APEX0 +82015/CSW", "e:/pervasive/staging/summit/C30-2015" => "e:/pervasive/test/APEX3 +02015/CSW", "e:/pervasive/staging/summit/C40-2015" => "e:/pervasive/test/APEX4 +02015/CSW", "e:/pervasive/staging/summit/C41-2015" => "e:/pervasive/test/APEX4 +12015/CSW", "e:/pervasive/staging/summit/C42-2015" => "e:/pervasive/test/APEX4 +22015/CSW", "e:/pervasive/staging/summit/C43-2015" => "e:/pervasive/test/APEX4 +32015/CSW", "e:/pervasive/staging/summit/C44-2015" => "e:/pervasive/test/APEX4 +42015/CSW", "e:/pervasive/staging/summit/C50-2015" => "e:/pervasive/test/APEX5 +02015/CSW", "e:/pervasive/staging/summit/C80-2015" => "e:/pervasive/test/APEX8 +02015/CSW", "e:/pervasive/staging/summit/C85-2015" => "e:/pervasive/test/APEX8 +52015/CSW", "e:/pervasive/staging/summit/C99-2015" => "e:/pervasive/test/APEX9 +92015/CSW" ); print "Hash assigned! \n\n"; ##Variables my $tm=localtime(); my ($day,$month,$year)=($tm->mday,$tm->mon+1,$tm->year+1900); my $MDY; my $dayday = sprintf("%02d",$day % 100); my $size = length($day); if($size < 2) { $MDY = "$month$dayday$year"; } else { $MDY = "$month$day$year"; } print "$MDY \n\n"; print "Variables and Time assigned! \n"; #Foreach C## -> /sql-alt/e/pervasive/APEXCCYYYY/CS## or /sql-alt/e/per +vasive/APEXCCYYYY/CSW foreach my $key(keys %compHash) { my $value = $compHash{$key}; move($key , $value); print "Successfuly moved $key to $value .\n"; }
Basically, everything passes, and it prints that it has Successfully moved the $key (being the first file path, original location) to the $value (final location, but it's not actually moving the files. Anyone see anything right off that I am doing wrong? Can I not use file paths in a hash for easy moving purposes? I tried, in PowerShell: move $key (wrote out the file path) , $value (wrote this path out as well, note both were copied from the hash including the quotes) and it worked succesfully. What am I missing? I *did* try write_file($key,$value); but this let me to "permission denied" I feel like I am missing something silly, and that it's likely an easy fix, but after 8-10 hours of wracking my brain I cannot seem to figure it out. ##EDIT Turns out - it's a permissions issue. If I am trying to move the folder to the destination by hand I am prompted with a window requesting admin access in order to perform the operation. I'd wager that this is the culprit as the script works... well... at least the error checking. Then my manual tests confirmed it's a permissions issue. Thanks a ton for your alls help on this.

Replies are listed 'Best First'.
Re: question regarding File::Copy, and hashes that contain file paths
by Your Mother (Archbishop) on Dec 12, 2015 at 16:12 UTC

    Most of the code is not being used at all… So the problem is probably that you are clobbering your hash somehow with the date stuff but you do not show it here. Or perhaps, judging by the modules you use, you aren’t creating the directories necessary before the move. Or maybe… this thing, File::PerlMove, is the culprit. Clobbering the move from File::Copy and having different usage. Try removing use File::PerlMove; and see if you get better error feedback.

    I would also encourage you in another direction. This is simpler and has built in feedback for failures, which of course happens on my box.

    use strictures; use Path::Tiny; my %files = ("e:/pervasive/staging/summit/C01" => "e:/pervasive/test/A +PEX012015/C01", "e:/pervasive/staging/summit/C02" => "e:/pervasive/test/A +PEX022015/C02", "e:/pervasive/staging/summit/C03" => "e:/pervasive/test/A +PEX032015/C03", ); for my $key ( keys %files ) { my $original = path($key); my $destination = $files{$key}; $original->move($destination); } __END__ moo@cow[88]~>perl pm/ Error rename on 'e:/pervasive/staging/summit/C01' -> 'e:/pervasive/tes +t/APEX012015/C01': No such file or directory at pm/ line 13 +.
      Error rename on 'e:/pervasive/staging/summit/C01' -> 'e:/pervasive/tes +t/APEX012015/C01': No such file or directory at pm/ line 13 +.
      This is now what I am running into. Any thoughts with dealing with this? It looks like it's searching for both the key -> value for the file path, or maybe I am misunderstanding the error.

        It is trying to do just what it says; move file1 (hash key) to file2 (value for that key). The -> is not code, just part of the message. So we’ll add a check for the original and a mkpath for the destination (if necessary) before doing the move; but it seems like you probably don’t have it unzipped the way you think–

        for my $key ( keys %files ) { my $original = path($key); die "There is no file $original" unless -f $original; my $destination = path($files{$key}); $destination->parent->mkpath unless -d $destination->parent; $original->move($destination); }
      Or, does this mean that the destination directory does not exist? In a separate decompression script I have (unzipped all of these files to the staging area) it creates the folder for me, so my assumption was that path would have that built in.
Re: question regarding File::Copy, and hashes that contain file paths
by flexvault (Monsignor) on Dec 12, 2015 at 16:38 UTC

    Welcome Leetsauce,

    If your script works for 1 ( then it will work for many ), then you only need to show us the following:

    my %compHash = ( "e:/pervasive/staging/summit/C01" => "e:/pervasive/test/APEX01201 +5/C01", ); foreach my $key(keys %compHash) { my $value = $compHash{$key}; my $ret = move($key , $value); if ( $ret ) ## If $ret == 1, then success { print "Successfuly moved |$key| to |$value| .\n"; } else { print "|$key| not moved to |$value|: $!\n"; } }
    plus any additional output you might expect. ( Notice I put '|' before and after the '$key' and '$value', to catch any spaces )

    From the documentation from 'File::Copy', it states 'move' works on files. Are the keys and values you are working with directories?


    "Well done is better than well said." - Benjamin Franklin

      Yes they are directories, and they have things inside them as well. Think that could be causing an issue? The for each that was posted before yours basically had the same result, with exception it was then telling me the new directory didn't exist.
        Yes they are directories, and they have things inside them as well.

        Take a look at File::Copy::Recursive

        #!/usr/bin/perl use strict; use File::Copy::Recursive qw(dircopy dirmove); use Time::Piece; my $MDY = localtime->mdy(''); print "$MDY \n\n"; my $src = 'e:/pervasive/staging/summit/'; my $dest = 'e:/pervasive/test/'; my @f = qw(01 02 03 04 05 06 07 08 30 40 41 42 43 44 44 50 80 85 99 ); my %compHash; for my $n (@f[0]){ # replace with @f if it works for first $compHash{'C'.$n} = 'APEX'.$n.'2015/C'.$n; $compHash{'C'.$n.'-2015'} = 'APEX'.$n.'2015/CSW'; }; foreach my $key (sort keys %compHash) { my $from = $src.$key; my $to = $dest.$compHash{$key}; print "Moving $from $to\n"; dirmove ( $from,$to ) or die "$!"; }


        You can test for file or directory by:

        if ( -f $file ) { .... } ## $file is a file elsif ( -d $file ) { ... } ## also could use '_' for speed else { ,,, } ## Not what we're looking for
        Also you may wish to look at 'glob' for getting information about directory contents ( files and/or directories ).

        Good Luck...Ed

        "Well done is better than well said." - Benjamin Franklin

      Now that I think about it, I could just create a new copy2 sub, and make it specifically deal with directories. I see the reference you're talking about now.
      Thank you for pointing this out. Sorry about posting as much of the script as I did. I wanted to be able to get my point across, but, as you stated, if it worked for 1 it would work for whatever the cap on a foreach loop is in perl =p Thanks for your help! I ended up using your Foreach because it handled it the way I wanted.

        Dear Leetsauce,

        My point wasn't to criticize your elaborate script, but to help you get better answers in the future. I'm glad you found a viable solution, but you should think of this as the start of your journey. Perl will allow you to do some amazing things, but you have a lot to learn, and it shouldn't be painful.

        Thank you for letting me know I helped you!

        Good Luck and Best Regards...Ed

        "Well done is better than well said." - Benjamin Franklin

Re: question regarding File::Copy, and hashes that contain file paths
by afoken (Canon) on Dec 12, 2015 at 19:58 UTC

    Just a little note: I see you using tons of modules, but neither strict nor warnings. Consider adding them, even if they don't help solve your current issue.


    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      The modules you see are just from the template I started with ( a previous script I had written ) and I didn't bother to go back and remove what wasn't needed. That said; some are needed in areas of this that I did not show. I tried to keep whatever incriminating info out as much as I was able. Wouldn't want my company knowing I'm posting code used for business ops on an open forum =p That said; I don't care. You all are some of the most helpful, and promptly so, people I have ever met on the interwebz.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1150117]
Approved by Albannach
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2022-05-21 16:10 GMT
Find Nodes?
    Voting Booth?
    Do you prefer to work remotely?

    Results (76 votes). Check out past polls.