while loop - Using perl to cycle through a list of values (x) and compare to another file with value ranges -
i have 2 files. 1 file has list of values so
nc_snpstest.txt
250 275 375 the other file has space delimited information. column 1 first value of range, column 2 has second value of range, column 5 has name of range, , column 8 has acts on range.
promoterstest.txt
20 100 yaax f yaax 5147 5.34 sigma70 99 200 300 yaaa r yaaap1 6482 6.54 sigma70 35 350 400 yaaa r yaaap2 6498 2.86 sigma70 51 i trying write script takes first line file 1 , parses file 2 line line see if value falls in range between first 2 columns.
when first match found, want print value file 1 , values in file 2 columns 5 , 8 line match. if no match found in file 2 print value file 1 , move on.
it seems should simple enough task i'm having issue cycling though both files.
this have written:
#!/usr/bin/perl use warnings; use strict; open $promoterfile, '<', 'promoterstest.txt' or die $!; open $snpsfile, '<', 'nc_snptest.txt' or die $!; open (file, ">promotermatchtest.txt"); while (my $snps = <$snpsfile>) { chomp ($snps); while (my $cord = <$promoterfile>) { chomp ($cord); @cordfile =split(/\s/, $cord); $lend = $cordfile[0]; $rend = $cordfile[1]; $promoter = $cordfile[4]; $sigmafactor = $cordfile[7]; foreach $a ($snps) { if ($a >= $lend && $a <= $rend) { print file "$a\t$cordfile[4]\t$cordfile[7]\n"; } else { print file "$a\n"; } } } } close file; close $promoterfile; close $snpsfile; exit; so far output looks so:
250 250 yaaap1 sigma70 250 where first line of file 1 being called , file 2 being cycled through. else command being used on each line of file 2 , script never cycles through other lines of file 1.
your problem you're not resetting progress through second file. read 1 line $snpsfile, check against ever line in second file.
but when start over, you're @ end of file, so:
while (my $cord = <$promoterfile>) { doesn't have read.
a quick fix add seek command in there, that'll make inefficient code. i'd suggest instead reading file 1 array, , referencing instead.
here's first draft rewrite may help.
#!/usr/bin/perl use warnings; use strict; use data::dumper; open $promoterfile, '<', 'promoterstest.txt' or die $!; open $snpsfile, '<', 'nc_snptest.txt' or die $!; open $output, ">", "promotermatchtest.txt" or die $!; @data; while (<$promoterfile>) { chomp; @cordfile = split; $lend = $cordfile[0]; $rend = $cordfile[1]; $promoter = $cordfile[4]; $sigmafactor = $cordfile[7]; push( @data, { lend => $cordfile[0], rend => $cordfile[1], promoter => $cordfile[4], sigmafactor => $cordfile[7] } ); } print dumper \@data; foreach $value (<$snpsfile>) { chomp $value; $found = 0; foreach $element (@data) { if ( $value >= $element->{lend} , $value <= $element->{rend} ) { #print "found $value\n"; print {$output} join( "\t", $value, $element->{promoter}, $element->{sigmafactor} ), "\n"; $found++; last; } } if ( not $found ) { print {$output} $value,"\n"; } } close $output; close $promoterfile; close $snpsfile; first - open file2, read in stuff in array of hashes. (if of elements there unique, key off instead.)
then read through snpsfile 1 line @ time, looking each key - printing if exists (at least once, on first hit) , printing key if doesn't.
this generates output:
250 yaaap1 sigma70 275 yaaap1 sigma70 375 yaaap2 sigma70 was aiming for?
aside 'dumper' statement outputs content of @data thus:
$var1 = [ { 'sigmafactor' => 'sigma70', 'promoter' => 'yaax', 'lend' => '20', 'rend' => '100' }, { 'sigmafactor' => 'sigma70', 'promoter' => 'yaaap1', 'rend' => '300', 'lend' => '200' }, { 'promoter' => 'yaaap2', 'sigmafactor' => 'sigma70', 'rend' => '400', 'lend' => '350' } ];
Comments
Post a Comment