On Sun, Aug 26, 2012 at 05:03:31PM +0000, Wang, Li wrote: > If in each line, without count of "N/N", all the other SNPs are > the same, delete this line. The "scaffold" indicates the > position of the SNP. > > My code is as follows: > #! /usr/bin/perl > use strict; > use warnings; > > my $usage="perl $0 <infile>\n"; > > my $in=shift or die $usage; > open (IN,$in) or die "Error: not found the $in\n";
You should be using the 3-argument version of open. It's safer and better practice. You should also use a lexical file handle. You probably want to include $! in your die string, which should contain an error message for the user. For example, the file might exist, but might not be readable by the user. open my $in_fh, '<', $in or die "open: $in: $!"; See `perldoc -f open'. > my $outfile = "SNPFilterSeg.txt"; > open (OUT, ">$outfile"); You should also use the 3-argument open and a lexical file handle here. > my $i; You should declare $i in the smallest scope that it is needed. You don't need it way out here so you should move it into the inner loop. > while (<IN>){ Best practice would have you declare a loop variable here. while(my $line = <$in_fh>) { There are a lot of things that can destroy $_ on you and it can lead to obscure bugs if you aren't careful. At least keep that in mind. > next if /^#/; > $_=~s/\n//; > $_=~s/\r//; Those two s/// look like a poor man's chomp. You may want to use chomp instead (it chomps $_ by default; otherwise pass an argument). chomp; See `perldoc -f chomp'. > my @tmp=split("\t",$_); > my @arr; > for ($i=1; $i<=30; $i++){ > next if $tmp[$i] =~ m/N\/N/; #filter out all "N/N" > @arr = split("\t",$tmp[$i]); #assign the filtered data to a new array > @arr > } > if (@arr == grep $arr[0] eq $_, @arr) { > print OUT "here\n"; > } > else{ > print OUT "@tmp\n"; > } > } > > close IN; > close OUT; Your indentation here looks broken. You should be careful to format your code cleanly. It can be vital to being able to read and understand it (not just you, but other people as well). Rather than using this inner loop and extra array, you can just use grep to eliminate the 'N/N' elements from the list. my @items = split /\t/, $_; @items = grep $_ ne 'N/N', @items; (You can do this all in one statement, but for your own clarity I separated it into two) The $_ ne 'N/N' part will be tested against each item in the list. ne is the stringwise not-equal-to operator. Only if the element does not equal 'N/N' will the item be included in the list returned by grep. @items should contain only the other items. See `perldoc perlop' and `perldoc -f grep'. Let us know if you still can't get it to work. Regards, -- Brandon McCaig <bamcc...@gmail.com> <bamcc...@castopulence.org> Castopulence Software <https://www.castopulence.org/> Blog <http://www.bamccaig.com/> perl -E '$_=q{V zrna gur orfg jvgu jung V fnl. }. q{Vg qbrfa'\''g nyjnlf fbhaq gung jnl.}; tr/A-Ma-mN-Zn-z/N-Zn-zA-Ma-m/;say'
signature.asc
Description: Digital signature