Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

mv files from dir1 to dir2

by lomSpace (Scribe)
on Jan 12, 2009 at 17:04 UTC ( [id://735738]=perlquestion: print w/replies, xml ) Need Help??

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

I need to mv files from dir1(/home/mydir/dir1/RESULTS 2008) to dir2 (/home/mydir/dir2)
When I run the script stdout shows the contents of /home/mydir/dir1/RESULTS 2008. That seems to work.
What is not working is the second part where the foreach should go through each subdir, which should be captured with
@files = grep /^(\d+\D\d)_(LacZ|pgK|SD|SU)(.*)$/,@files;
I don't see those files. Can't mv what you can't see.
use warnings; use strict; # goes from current dir, and looks thru # a subdir named 7, for subdirs starting with # Jan_2009_, then goes into that subdir and finds # files begiining with a or b or c # making your particular regexes is up to you #opendir ( my $rs, "tarfs-orion/orion/Data/Sequencing_Result<br>/RESUL +TS 2009"); my $topdir = "/home/mgavi/testdir1/RESULTS 2008"; my @subdirs = get_sub_dirs($topdir); my $newdir = "/home/mgavi/testdir2"; sub get_sub_dirs { my $dir = shift; opendir my $dh, $dir or die "Error: $!"; print "$dh\n"; my @dirs = readdir $dh; print "@dirs\n"; @dirs = grep /^Results(.*)$/,@dirs; closedir $dh; return @dirs; } print "subdirs = @subdirs\n"; foreach my $dir(@subdirs){ opendir my $dh, "$topdir/$dir" or die "Error: $!"; my @files = readdir $dh; print "raw files = @files\n"; @files = grep /^(\d+\D\d)_(LacZ|pgK|SD|SU)(.*)$/,@files; print "$dir -> @files\n"; foreach my $file(@files){ system( "mv $topdir/$dir/$file $newdir/$file"); } closedir $dh; }
In need of perl wisdom

Replies are listed 'Best First'.
Re: mv files from dir1 to dir2
by zentara (Archbishop) on Jan 12, 2009 at 17:13 UTC
      Here are file name examples:
      12774L1_LacZ.SEE.rc_C06_2008-12-01.ab1
      12774L1_pgK.Neo.2fw_D06_2008-12-01.ab1,
      12774L1_SD_B06_2008-12-01.ab1
      12774L1_SU_A06_2008-12-01.ab1
      My regex,/^(\d+\D\d)_(LacZ|pgK|SD|SU)(.*)$/, should capture any of these?
        Yes. But you could have answered that question yourself with a short experiment:
        use strict; use warnings; while (<DATA>) { if (/^(\d+\D\d)_(LacZ|pgK|SD|SU)(.*)$/) { print "match: $_"; print ' $1', " is $1\n"; print ' $2', " is $2\n"; print ' $3', " is $3\n"; } else { print "no match: $_"; } } __DATA__ 12774L1_LacZ.SEE.rc_C06_2008-12-01.ab1 12774L1_pgK.Neo.2fw_D06_2008-12-01.ab1 12774L1_SD_B06_2008-12-01.ab1 12774L1_SU_A06_2008-12-01.ab1 foo.bar

        prints:

        match: 12774L1_LacZ.SEE.rc_C06_2008-12-01.ab1 $1 is 12774L1 $2 is LacZ $3 is .SEE.rc_C06_2008-12-01.ab1 match: 12774L1_pgK.Neo.2fw_D06_2008-12-01.ab1 $1 is 12774L1 $2 is pgK $3 is .Neo.2fw_D06_2008-12-01.ab1 match: 12774L1_SD_B06_2008-12-01.ab1 $1 is 12774L1 $2 is SD $3 is _B06_2008-12-01.ab1 match: 12774L1_SU_A06_2008-12-01.ab1 $1 is 12774L1 $2 is SU $3 is _A06_2008-12-01.ab1 no match: foo.bar

        Update: Furthermore, grep properly filters out the "foo.bar" file I injected:

        It looks to me, like your $topdir, in your script, has Results_2008 on the hardcoded path, where my script, finds Results_2008 as a subdir, as your original specification was. So you have a path_logic error.

        I'm not really a human, but I play one on earth Remember How Lucky You Are
        Your script with those filenames works here:

        in /testdir1/Results_2008:

        12774L1_LacZ.SEE.rc_C06_2008-12-01.ab1 12774L1_SD_B06_2008-12-01.ab1 12774L1_pgK.Neo.2fw_D06_2008-12-01.ab1 12774L1_SU_A06_2008-12-01.ab1

        in /testdir1/Results_2009: no files

        My script:

        #!/usr/bin/perl use warnings; use strict; my $topdir = "/home/zentara/testdir1"; my @subdirs = get_sub_dirs($topdir); my $newdir = "/home/zentara/testdir2"; sub get_sub_dirs { my $dir = shift; opendir my $dh, $dir or die "Error: $!"; # print "$dh\n"; #this is your glob my @dirs = readdir $dh; @dirs = grep /^Results(.*)$/,@dirs; closedir $dh; return @dirs; } print "subdirs = @subdirs\n"; foreach my $dir(@subdirs){ opendir my $dh, "$topdir/$dir" or die "Error: $!"; my @files = readdir $dh; print "raw files = @files\n"; @files = grep /^(\d+\D\d)_(LacZ|pgK|SD|SU)(.*)$/,@files; print "$dir -> @files\n"; foreach my $file(@files){ # system( "mv $topdir/$dir/$file $newdir/$file"); } closedir $dh; }
        OUTPUT:

        subdirs = Results_2008 Results_2009

        raw files = . .. 12774L1_SU_A06_2008-12-01.ab1 12774L1_pgK.Neo.2fw_D06_2008-12-01.ab1 12774L1_LacZ.SEE.rc_C06_2008-12-01.ab1 12774L1_SD_B06_2008-12-01.ab1

        Results_2008 -> 12774L1_SU_A06_2008-12-01.ab1 12774L1_pgK.Neo.2fw_D06_2008-12-01.ab1 12774L1_LacZ.SEE.rc_C06_2008-12-01.ab1 12774L1_SD_B06_2008-12-01.ab1

        raw files = . .. Results_2009 ->

        You must have some overlooked spelling error in your pathnames or something?


        I'm not really a human, but I play one on earth Remember How Lucky You Are
Re: mv files from dir1 to dir2
by CountZero (Bishop) on Jan 12, 2009 at 18:51 UTC
    Ending a regex with (.*)$ is generally quite useless.

    What you are saying is that after the first part of the regex, there should be something (anything at all) or nothing until the end. As it could be anything (including nothing), why bother? You can safely drop it. There is no need to anchor your regexp on both sides, esp. not with '.*'.

    Of course you capture the .* part but you never use the captures, so you can drop all the parentheses as well and gain a bit of speed.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      True, thanks!
Re: mv files from dir1 to dir2
by gasho (Beadle) on Jan 12, 2009 at 18:40 UTC
    Maybe This will help
    use File::Find::Rule; sub fullPathToFile #($StartDirectory,$SearchExpression) { my ($StartDirectory,$SearchExpression)= @_; my(@files,$IsWin1,$IsWin2,$IsWin3,@File_Paths,$Fl,@d,$c); @files = File::Find::Rule->file()->name("$SearchExpression")->in(" +$StartDirectory"); $IsWin1=substr($StartDirectory,1,1); $IsWin2=substr($StartDirectory,0,2); $IsWin3=substr($StartDirectory,0,1); print "HO HO:$IsWin3\n"; #If $StartDirectory starts with "D:\" or "\\\\" or" \" than it +is Win replace / with \ if( ($IsWin1 eq ':')||($IsWin2 eq '\\\\') ||($IsWin3 eq '\\') + ) { foreach $Fl (@files) { @d=split(/\//,$Fl); $c=join ("\\",@d); push(@File_Paths,$c); } } else { @File_Paths=@files; } return @File_Paths; } $LocationOfTheScriptsDirectory='/Harness/RootOfAllFiles'; $newdir='/TEST'; $SearchExp='*.abl'; @AllFilePaths=fullPathToFile($LocationOfTheScriptsDirectory,$SearchExp +); foreach $file (@AllFilePaths){ @A2 =split(/\//,$file); $fileName=$A2[-1]; system( "cp $file $newdir/$fileName"); }
    (: Life is short enjoy it :)
      Not clear what this is supposed to do?
Re: mv files from dir1 to dir2
by targetsmart (Curate) on Jan 13, 2009 at 13:34 UTC
    I am not exactly replying to your problem, but recently I found that system(mv ..) couldn't give proper return status, if we would have IGNORED the CHLD signal or improper signal handler set for CHLD.
    This is because system(mv) generally forks a process and system function depends on CHLD signal internally to provide us the return status. If we ignore SIGCHLD we won't get proper return value from system function.
    I have put this in interest of beginner monks.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (7)
As of 2024-04-19 11:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found