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

Hi All, I have a script which takes Input from a file(which is a plate name in numbers will be 5 -6 digits long). And uses that number to fetch the information attached to that from the database and writes in another file. The output file would be something like this.
1,WG0045068-DNA,A01,0,102186_A01_WTCCCT519791,Homo sapiens,male,,13,50 +,-,,0,,,,Blood 2,WG0045068-DNA,B01,0,102186_B01_WTCCCT519793,Homo sapiens,male,,13,50 +,-,,0,,,,Blood 3,WG0045068-DNA,C01,0,102186_C01_WTCCCT519805,Homo sapiens,female,,13, +50,-,,0,,,,Blood 4,WG0045068-DNA,D01,0,102186_D01_WTCCCT519796,Homo sapiens,male,,13,50 +,-,,0,,,,Blood 5,WG0045068-DNA,E01,0,102186_E01_WTCCCT519797,Homo sapiens,female,,13, +50,-,,0,,,,Blood
where the 1, 2, 3, 4, 5 are line numbers. What I am stuck with is, If I have more than one plate name in the file I get the line numbers iterating for the other plates as well.
6,WG0045066-DNA,A01,0,102176_A01_WTCCCT527545,Homo sapiens,female,,13, +50,Nucleon BACC3 kit,,0,,,,Blood 7,WG0045066-DNA,B01,0,102176_B01_WTCCCT527498,Homo sapiens,female,,13, +50,Nucleon BACC3 kit,,0,,,,Blood 8,WG0045066-DNA,C01,0,102176_C01_WTCCCT527510,Homo sapiens,male,,13,50 +,Nucleon BACC3 kit,,0,,,,Blood 9,WG0045066-DNA,D01,0,102176_D01_WTCCCT527522,Homo sapiens,male,,13,50 +,Nucleon BACC3 kit,,0,,,,Blood
I need to start the other plate as 1, 2, 3, 4... until it has values attached to it. Some plates may have 96 lines and some may have as little as 1. I could get the number of lines that each plate has from the database. I have atached my code along with this for you. Could you suggests some way to get to this!!! Thanks a lot in advance ...
elsif($output eq "Inhouse") { my $n= 1; print OUT ("Row,Institute Plate Label,Well,Is Control,Institut +e Sample Label,Species,Sex,Comments,Volume (ul),Conc (ng/ul),Extracti +on Method,WGA Method (if Applicable),Mass of DNA used in WGA,Parent 1 +,Parent 2,Replicate(s),Tissue Source\n"); print OUT "\n\n"; foreach my $sam(@order){ if($save{$sam}{clone} =~ /BLANK|Water/i){ print OUT "$n,$save{$sam}{platename},$save{$sam}{well},,$s +ave{$sam}{plateid}$save{$sam}{well}_BLANK,,,BLANK,,,,,,,,,,\n"; $n++; } if (!$save{$sam}{platename}) { print OUT "$n,$save{$sam}{plateid},$save{$sam}{well},$save +{$sam}{case},$save{$sam}{plateid}_$save{$sam}{well}_$save{$sam}{clone +},Homo sapiens,$save{$sam}{gender},,$save{$sam}{vol},50,$save{$sam}{e +xtmethod},,,$save{$sam}{father},$save{$sam}{mother},,$save{$sam}{sour +ce}\n"; $n++; } else { #unless ($n == $save{$sam}{count}) { print OUT "$n,$save{$sam}{platename},$save{$sam}{well} +,$save{$sam}{case},$save{$sam}{plateid}_$save{$sam}{well}_$save{$sam} +{clone},Homo sapiens,$save{$sam}{gender},,$save{$sam}{vol},50,$save{$ +sam}{extmethod},,0,$save{$sam}{father},$save{$sam}{mother},,$save{$sa +m}{source}\n"; $n++; } } } }
Where in, the @order has all the information from the database and %save is a hash.And $save{$sam}{count} is the number of lines it has got for each plate. The plates here are 102186 and 102176.

Replies are listed 'Best First'.
Re: Iteration in perl
by baxy77bax (Deacon) on Apr 03, 2009 at 10:21 UTC
    ok, this looks like some perl API for some type of database: but i'm having difficulties understanding you . do you want your results to look like this :
    1,WG0045068-DNA,A01,0,102186_A01_WTCCCT519791,... 2,WG0045068-DNA,B01,0,102186_B01_WTCCCT519793,... 3,WG0045068-DNA,C01,0,102186_C01_WTCCCT519805,... 1,WG0045066-DNA,A01,0,102176_A01_WTCCCT527545,... 2,WG0045066-DNA,B01,0,102176_B01_WTCCCT527498,...
    or ... could you give us an example of how the results should look like ...

    Update:

    let me simplify :

    i have i file with lines like :

    WG0045068-DNA,A01,0,102186_A01_WTCCCT519791,... WG0045068-DNA,B01,0,102186_B01_WTCCCT519793,... WG0045068-DNA,C01,0,102186_C01_WTCCCT519805,... WG0045068-DNA,A01,0,102187_A01_WTCCCT519791,... WG0045068-DNA,B01,0,102188_B01_WTCCCT519793,... WG0045068-DNA,C01,0,102187_C01_WTCCCT519805,... WG0045068-DNA,A01,0,102187_A01_WTCCCT519791,... WG0045068-DNA,B01,0,102188_B01_WTCCCT519793,... WG0045068-DNA,C01,0,102186_C11_WTCCCT519805,... and i want to get: 1,WG0045068-DNA,A01,0,102186_A01_WTCCCT519791,... 2,WG0045068-DNA,B01,0,102186_B01_WTCCCT519793,... 3,WG0045068-DNA,C01,0,102186_C01_WTCCCT519805,... 4,WG0045068-DNA,C01,0,102186_C11_WTCCCT519805,... 1,WG0045068-DNA,A01,0,102187_A01_WTCCCT519791,... 2,WG0045068-DNA,C01,0,102187_C01_WTCCCT519805,... 3,WG0045068-DNA,A01,0,102187_A01_WTCCCT519791,... 1,WG0045068-DNA,B01,0,102188_B01_WTCCCT519793,... 2,WG0045068-DNA,B01,0,102188_B01_WTCCCT519793,...
    to get this you could creata some counter like this:
    open (FILE1, "<", "filein.txt") || die "$!"; open (FILE2, ">", "fileout.out") || die "$!"; my $counter; while(<FILE1>){ m/.+,.+,\d+,(\d+)_.+/; $counter->{$1}++ ; print FILE2 "$counter->{$1},$_"; } close FILE1; close FILE2; result would be : 1,WG0045068-DNA,A01,0,102186_A01_WTCCCT519791,... 2,WG0045068-DNA,B01,0,102186_B01_WTCCCT519793,... 3,WG0045068-DNA,C01,0,102186_C01_WTCCCT519805,... 1,WG0045068-DNA,A01,0,102187_A01_WTCCCT519791,... 1,WG0045068-DNA,B01,0,102188_B01_WTCCCT519793,... 2,WG0045068-DNA,C01,0,102187_C01_WTCCCT519805,... 3,WG0045068-DNA,A01,0,102187_A01_WTCCCT519791,... 2,WG0045068-DNA,B01,0,102188_B01_WTCCCT519793,... 4,WG0045068-DNA,C01,0,102186_C11_WTCCCT519805,... not sorted, but sorting should not be a problem :)
    i'm still not sure if this is what you would like to accomplish :)

    Update 2:

    ok cool, so you have a file or some variable with some data in it

    input.file 102186 102176
    , what i would do is hash that data
    open (FILEIN, "<", "input.file") || die "$!"; my $counter; while(<FILEIN>){ $counter->{$_} = 0; } close FILEIN;
    and now you have a counter so what i would do next is :
    elsif($output eq "Inhouse") { ... and here just implemente the counter. you can do the same thing for fo +r previous decisions, if needed ... else { $counter->{$save{$sam}{plateid}}++; print OUT "$counter->{$save{$sam}{plateid}},$save{$sam +}{platename},$save{$sam}{well},$save{$sam}{case},$save{$sam}{plateid} +_$save{$sam}{well}_$save{$sam}{clone},Homo sapiens,$save{$sam}{gender +},,$save{$sam}{vol},50,$save{$sam}{extmethod},,0,$save{$sam}{father}, +$save{$sam}{mother},,$save{$sam}{source}\n"; } ...
      Exactly .. Thats How it should be.But the line numbers should vary depending on the $save{$sam}{count} number which is the number of lines of information available for that plate.
      Hi, Thanks for your time .But, My Input file is something like this:
      102186 102176
      And I need to get the output like
      1,WG0045068-DNA,A01,0,102186_A01_WTCCCT519791,... 2,WG0045068-DNA,B01,0,102186_B01_WTCCCT519793,... 3,WG0045068-DNA,C01,0,102186_C01_WTCCCT519805,... 1,WG0045066-DNA,A01,0,102176_A01_WTCCCT527545,... 2,WG0045066-DNA,B01,0,102176_B01_WTCCCT527498,...
      At the moment I am getting the output as:
      1,WG0045068-DNA,A01,0,102186_A01_WTCCCT519791,... 2,WG0045068-DNA,B01,0,102186_B01_WTCCCT519793,... 3,WG0045068-DNA,C01,0,102186_C01_WTCCCT519805,... 4,WG0045066-DNA,A01,0,102176_A01_WTCCCT527545,... 5,WG0045066-DNA,B01,0,102176_B01_WTCCCT527498,...
      Does this help by any means??? Thanks!!!

        You should just check in the beginning of every iteration if platename is changed, and if it is, just reset numeration. Perhaps the following snippet would help you. Note that I not tested it

        my $oldname; # here we will store previous name foreach my $sam (@order) { # here is the current name my $platename = $save{$sam}{platename} || $save{$sam}{plateid}; # if name is changed, reset n to 1 $n = 1 unless $patename eq $oldname; if ( $save{$sam}{clone} =~ /BLANK|Water/i ) { print OUT "$n,$save{$sam}{platename},$save{$sam}{well},,$save{$sam}{plateid}$sav +e{$sam}{well}_BLANK,,,BLANK,,,,,,,,,,\n"; $n++; } print OUT "$n,$platename,$save{$sam}{well},$save{$sam}{case},$save{$sam}{plateid +}_$save{$sam}{well}_$save{$sam}{clone},Homo sapiens,$save{$sam}{gende +r},,$save{$sam}{vol},50,$save{$sam}{extmethod},,0,$save{$sam}{father} +,$save{$sam}{mother},,$save{$sam}{source}\n"; $n++; # store platename $oldname = $platename; }