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

I need to do the following: 1. opendir 2. Check folder name for current month year. a. If not current skip. b. If current then opendir. 3. Check the first file's name in the dir a. If 1st file's name does not contain, one of four regex's. then skip. b. Else read file names. c. Iterate through the files and parse out the id #. d. create a hash with the file name and parsed id# to match files with the same id# that occur exactly four times. e. save those that meet criteria of step 3d. Possibly in a glob. 4. chdir 5. mv data from step 3e to working dir. Next do: a. create another hash to match id# from step 3c with subdir names in working dir. b. Upon match of subdir open it and mkdir with id#_sa. c. Deposit the moved files that have same id# as subdir name into the newly created dir id#_sa.(id#_sa ex. 12335_sa) Here is my code:
#!/usr/bin/perl -w use strict; use warnings; use File::Copy; opendir( RS, "seqresults/resultsdate"); my %rs; while (defined($rs = readdir (RS))) { @rs_info = split(/_/,$rs); my $idnum= $fields[0]; if ($count == null){ ${maid}=1; }else{ ${maid}=$count+1; } foreach my $maid ( keys %h ){ if ($h{$maid}==4){ #call routine to do your copy logic } } } closedir RS; opendir( SA, "/newdir/");
# This is what i have thus far. Need help!
  • Comment on Processing data in on dir and copying, then processing into another dir
  • Download Code

Replies are listed 'Best First'.
Re: Processing data in on dir and copying, then processing into another dir
by zentara (Cardinal) on Jan 08, 2009 at 17:40 UTC
    Here is one way, by using grep on your dir and file lists. It's a start that should show the way. The logic is greatly simplified by separating the subdir and file search. I'm sure this code can be condensed, but your list of requirements is so big, you are better off breaking it into small steps to aid in debugging.
    #!/usr/bin/perl 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 my $topdir = '7'; my @subdirs = get_sub_dirs($topdir); sub get_sub_dirs { my $dir = shift; opendir my $dh, $dir or die "Error: $!"; my @dirs = readdir $dh; @dirs = grep /^Jan_2009_(.*)$/,@dirs; closedir $dh; return @dirs; } print "@subdirs\n"; my @files; foreach my $dir(@subdirs){ opendir my $dh, "$topdir/$dir" or die "Error: $!"; @files = readdir $dh; @files = grep /^(a|b|c)(.*)$/,@files; closedir $dh; } print "@files\n"; #Now you can regex your files, etc

    I'm not really a human, but I play one on earth Remember How Lucky You Are
      I want to opendir "../Data/Sequencing_Results/Results 2009" for reading, then check subdirs "../Data/Sequencing_Results/Results 2009/*". Ex. "../Results 2009/Jan 2009". So is $topdir = "../Data/Sequencing_Results/Results 2009" ?
        If you want to open dir "../Data/Sequencing_Results/Results 2009", it means you are jumping up one directory. You should substitute your dirs in the example I gave, and see what you get. Using relative pathnames can always be tricky, so if in doubt, use the full system path, then you don't need to worry about the dot's
        #!/usr/bin/perl use File::Spec $filename= $0; $abs_path = File::Spec->rel2abs($filename); print "$abs_path\n"; $filename = File::Spec->abs2rel($abs_path); print "$filename\n";
        So in my example, say you were in a dir named 6, your topdir would be "../7" , as you suggest. But setup a test script that just does printouts with no copying, and see how your syntax works. Usually it's NOT a good idea to jump up dirs with .., so I would go with full path names and that will solve your problem.

        I'm not really a human, but I play one on earth Remember How Lucky You Are
      ok so I have just added system("mv @files $newdir"); but nothing is being mv to $newdir?
        mv won't work on an array like that, you need (untested and havn't checked if you $newdir is an absolute path or not)
        foreach my $file(@files){ system( "mv $file $newdir/$file"); }
        and you might want to check to see if the newfiles were actually moved, by looping thru @files again, and see if they are in $newdir.

        I'm not really a human, but I play one on earth Remember How Lucky You Are
Re: Processing data in on dir and copying, then processing into another dir
by igelkott (Priest) on Jan 08, 2009 at 17:59 UTC
    Check the first file's name in the dir

    Seems dangerous to rely on what will be the first file unless you have quite strict control over what might be in these folders.

      The files that I am interested in will consistently look similar to this: ^12112L5_LacZ,^12112L5_pgK, ^12112L5_SU, or ^12112L5_SD. If the first file in the folders name does not correspond to any of the afore mentioned then I know to skip to search the next folder. I will probably run a cron job so that way I will know exactly which folder to look at.