PERL练习汇总

1.1 读入file,将序列变成一行输出
use strict;      #报错语句
use warnings;

open (FA,"file") or die $!;   #打开文件句柄
open (FB,">file1") or die $!;

while (<FA>){
	chomp;
	print FB $_;
}

print FB "\n";

#我写的
#!/usr/bin/perl
use strict;
use warnings;

open (FILE,"/home/qian.liu/perl/file") or die "Can't read file";  ###文件句柄读取时要注明输入还是输出
while(my $test = <FILE> ){
	chomp($test) ;
	print $test;
}

close FILE;

输入的方式:

键盘输入:$line=<STDIN>;chomp($line);

钻石输入符:<>

调用参数:@ARGV

输出的方式:

print

printf:可以格式化输出

文件句柄:

open CONFIG ,"dino";  会打开CONFIG的文件句柄,让它指向:dino文件,文件中的内容可以读入到程序中

open CONFIG,">dino"; 用>来声明此文件是用来输入的,与上一行意义相同

open BEDROCK ,">fred";用来创建一个新的文件,打开BEDROCK,输出到新文件fred,如果已经存在一个fred,就会清除并命名一个新的输出到fred

open LOG,">>logfile";文件如果本身存在就会直接在原有文件的内容后面添加新结果,如果不存在就创建一个新文件,然后输出

2.1读入file,将前5行打印到屏幕

我的写法:思路,想利用正则表达式匹配换行符来匹配相应行数,问题如果求的行数不是第一行就不适用。

#!/usr/bin/perl
use strict;
use warnings;

our ($i,$test);
open (FILE,"/home/qian.liu/perl/file") or die "Can't read file";

my $i = 1;
if ($i<=5) {
	while($test =<FILE>){
		$test =~/^\n/;
		$i++;
		
	}
	print $test;
}

close FILE;

use strict;
use warnings;

open (FA,"file") or die $!;
open (FB,">file2") or die $!;

my @d=<FA>;

for (my $i=0;$i<=4;$i++){
	print FB $d[$i];
}

答案是使用数组。


1.3计算1 2 3 4 5的最大值,最小值和平均数

use strict;
use warnings;

my (@d,$total,$i,$ave);
@d=qw /1 2 3 4 5/;
$total=0;
$i=0;
@d=sort @d;

for ($i=0;$i<scalar @d;$i++){
	$total+=$d[$i];
}
$ave=$total/scalar @d;

print "The max is $d[-1]\n";
print "The min is $d[0]\n";
print "The average is $ave\n";

答案思路很清晰

scalar是求个数的函数,sort是排序函数

#!/usr/bin/perl
use strict;
use warnings;

my @array=qw(1 2 3 4 5);
my @sort_array= sort @array;
my $num= scalar @array;

print "最大值:$sort_array[$#sort_array]\n";
print "最小值:$sort_array[0]\n";
print "个数: $num\n";

sub average{
		my ($sum,$num,$ave);

		$num = scalar @array; 
		foreach $sum (@sort_array) {
			$sum += @sort_array;     ###不知道这种写法是否可行
		}
		$ave = $sum / $num ;

		printf "平均值:$ave";
}

要注意一下for循环和foreach循环,foreach是遍历

1.4将以下字母c a e w i m j q z s n 存入数组,排序后输出

use strict;
use warnings;

my @d;
@d=qw /c a e w i m j q z s n/;
@d=sort {$a cmp $b} @d;
print @d,"\n";

用排序函数sort就能解决,注意判断数字大小的时候用<=>

1.5

1.     以下是一个加班表,写一个程序,做到输入一个姓名就能告诉这个人哪天加班。(提示用hash做)

姓名

加班日期

David

Monday

Stephen

Wednesday

Kobe

Friday

LeBron

Monday

 

use strict;
use warnings;

my %overtime_table=(
'David'=> 'Monday',
'Stephen'=> 'Wednesday',
'Kobe'=>'Friday',
'LeBron'=>'Monday',
);
print "please enter a name: ";
chomp(my $name = <STDIN>);

if (defined $overtime_table{$name}){
	print "$name\'s overtime date is $overtime_table{$name}.\n";
}else{
	print "$name didn't work here.\n";
}
弄清Key和value的关系,注意hash的定义

#!/usr/bin/perl
use strict;
use warnings;

my %hash = ("David" => "Monday","Stephen" => "Wednesday","Kobe" => "Friday","LeBron" => "Monday");

print "plesae input your name:\n";
chomp (my $name= <STDIN> );

print "$name working time is: $hash{$name} .\n";
2.1

1.        1.test文件共有两列信息,第一列为序列编号,第二列为序列,请按以下四项要求进行过滤和处理,然后将符合要求的序列编号和序列输出到新文件中(结果如图所示)。(30分)

1)每条序列需以ATG开头或者含有ATATAT

2)每条序列长度需大于125

3)如果符合上述两项要求的序列中含有除ATCG以外的字符,请替换成N

4)请在每一行的末端加上poly-A/poly-T的序列及其在原序列中的位置。

#!/usr/bin/perl
use strict;
use warnings;

open IN, "<", $ARGV[0];
while (my $line = <IN>){
    if($line =~ /^(\S+)\s+((ATG)|(.*?ATATAT)\S+)/){
       my $header = $1;
       my $seq = $2;
       my $length = length $seq;
       if ($length > 125){  
           $seq =~ s/[^ATCG]/N/g;
       
           if($seq =~ /.*?(T+)$/){
              my $poly_T = $1;
              my $pos = $length-length($poly_T)+1;
              print $header,"\t",$seq,"\t",$poly_T,"\t",$pos,"\n";
           }
           elsif($seq =~ /.*?(A+)$/){
              my $poly_A = $1;
              my $pos = $length-length($poly_A)+1;
              print $header,"\t",$seq,"\t",$poly_A,"\t",$pos,"\n";
           }
       }
    }
}
close IN

__END__

注意poly-A/T的表达



2.2 提取2.test文件中每行第三列为CDS的信息。输出内容及格式为IDparentprotein_idproduct(结果如图所示)。(20分)

#!/usr/bin/perl
use strict;
use warnings;

open IN, "<", $ARGV[0];
while (my $line = <IN>){
   next,if($line =~ /^#/);
   if($line =~ /ID=(.*?);Parent=(.*?);.*?product=(.*?);.*?protein_id=(.*?);/){
      print $1,"\t",$2,"\t",$3,"\t",$4,"\n";
   }
}
close IN;

__END__

思路:首先要去除注释信息,所以匹配到#就删除,注意此处用的.*?可以匹配任意多字符,用()来捕捉信息,以分号为界


2.33.test序列文件(第一个碱基T的位置记为1)中提取出gene0的碱基序列,已知gene0的起始位置是319,终止位置是1674。(15分)

#!/usr/bin/perl
use strict;
use warnings;

open IN, "<", $ARGV[0];
my $seq = <IN>;
close IN;

my $gene0_seq = substr($seq,318,1674-319+1);
print ">gene0\n",$gene0_seq,"\n";

__END__


提取字符串用substr函数,注意它给出的输出文件格式。


2.4 4.test文件中记录了若干数字,并用“,”将其分隔开来,请计算并输出这些数字的平均值(保留两位小数)和中位数。(20分)

#!/usr/bin/perl
use strict;
use warnings;

open IN, "<", $ARGV[0];
my $number_line = <IN>;
close IN;

my @numbers = split(",",$number_line);

my @sort_numbers = sort {$a <=> $b} @numbers;

my $number = scalar @sort_numbers;
my $sum = 0;
my $median = 0;

foreach my $ele (@sort_numbers){
   $sum = $sum+$ele;                   ###1.3的写法
}
my $mean = sprintf "%0.2f",$sum/$number;

if($number%2 == 0){
   my $index1 = $number/2-1;  
   my $index2 = $number/2;
   $median = ($sort_numbers[$index1]+ $sort_numbers[$index2])/2;
}
else{
   my $index = ($number/2+0.5)-1;
   $median = $sort_numbers[$index];
}

print "mean:\t",$mean,"\n","median:\t",$median,"\n";

__END__

注:数组和标量的使用分界不清,注意中位数的定义。

#!/usr/bin/perl
use strict;
use warnings;

open (FILE,"4.test") or die "Can't open !";

while (<FILE>) {
	my $data=~s/,/\s/;       #将,换成空格

	sub mid{                              主程序和子程序混乱
		my $count=scalar $data;
		my $test= sort $data;
		if(($count%2)!=0){
			return ($test[int(($count -1)/2)]);
		}
		elsif(($count%2) == 0){
			return ($test[int($count -1)/2]+$tset[int($count/2)])/2;
		}
	}

	sub average{
		my ($sum,$num,$ave);

		$num = scalar $data; 
		foreach $sum ($data) {
			$sum += $data;
		}
		$ave = $sum / $num ;

		printf "%.3f", $ave;
	}

}

close FILE;

编写子程序以后,前面是主程序,里面可以调用子程序,然后后面是子程序。

思路很重要,要弄懂子程序的应用


2.5 5.test记录了五位学生在一次测验中的成绩,第一列为学生姓名,第二列为考试分数,请按照分数从高到低重新排序输出到新的文件中(结果如图所示)。(提示使用哈希,键值排序)(15分)

#!/usr/bin/perl
use strict;
use warnings;

my %hash;

open IN, "<", "$ARGV[0]";
while (my $line = <IN>){
   if($line =~ /^(\S+)\s+(\S+)/){
      $hash{$1} = $2;      #将key 和value 对应
   }
}
close IN;

my @keys = sort {$hash{$b} <=> $hash{$a}} keys %hash;

foreach my $key (@keys){
   print $key,"\t",$hash{$key},"\n";
}

__END__
#!/usr/bin/perl
use strict;
use warnings;

my %score = ("Jim" => "67","Lily" => "81","Lucy" => "80","Harry" => "79","Ada" => "90");

foreach my $key ( sort { $score{$b} <=> $score{$a} } keys %score ) { 
     my $value = $score{$key}; 
	 print ("$key\t$value\n");
}

我是将文件手动输入了

3.1 

一、 FASTA文件处理 40分)

输入文件 test.fa如下,以第一条序列为例>ENSRNOT00000000957 gene=F1M7K0_RATCDS=1-1104 依次为基因ID、名称、编码区位置以下为碱基序列

1、将序列读入哈希变量%gene_fasta(建议  key为“基因ID value为“碱基序列”)

2、输出第一条(ENSRNOT00000000957)序列的反向互补序列

3、输出表格依次为基因ID、名称、编码区起始位、编码区终止位,部分表格如下

4、查找其中最长的序列,输出ID编号,与碱基信息

5、统计长度在200~500之间的序列,并按长度排序输出 ID 和长度部分表格如下


#!/usr/bin1/perl

use strict;
use warnings;
my ($id,$seq,$seq1,$seq1_1,$b,$d,@seq1,@a,@c,%gene_fasta);

#write into haxi
open (FA,"<test.fa")||die $!;
$id='first';
while (<FA>){
	chomp;	
	if (/^>/){
		$gene_fasta{$id}=$seq;
		$seq='';
		$id=$_;
	}else{
		$seq.=$_;
	}	
}
delete $gene_fasta{"first"};
close FA;
#reverse,complement
$seq1=$gene_fasta{">ENSRNOT00000000957 gene=F1M7K0_RAT CDS=1-1104"};
chomp $seq1;
@seq1=split //,$seq1;
@seq1=reverse @seq1;
$seq1_1=join '',@seq1;
$seq1_1=~ tr/ACGTacgt/TGCAtgca/;
print $seq1_1;

#blank
@a=keys %gene_fasta;
foreach $b(@a){
	chomp $b;
	@c=split '',$b;
	$c[0]=~s/>//g;
	$c[1]=~s/gene=//g;
	$d=$c[2];
	if($d=~/CDS=(\d+)-(\d+)/s){
		print $c[0]."\t".$c[1]."\t".$1."\t".$2\n";
		}
}

 3.2

二.文件处理  60

存在文件gene.annot.xls部分如下包括两列ID   基因名称文件enrich.xls文件倒数第三列包含基因ID

1、请编写脚本将第三列的基因ID修改为基因ID|基因名称的格式,如enrich.add_annot.xls 所示

 

#!usr/bin/perl

use strict;
use warnings;
my (@a,@b,@c,$d,$i,$id,$name,$gene,%h,%k);

#open file gene.annot.xls and store into %h #
open (AN,"<gene.annot.xls")||die "can not open!";

while(<AN>){
	if (/^Ensembl/){
		next;
	}
	chomp;
	@a=split;
	$id=$a[0];
	$name=$a[1];
	$h{$id}=$name;
}
close AN;

#open enrich.xls and make changes at gene name,then store the information in enrich.add_annot.xls
open (EN,"<enrich.xls")||die "can not open!";
open (OUT,">enrich.add_annot.xls")||die "can not creat!";

while(<EN>){
	if (/^#/){
		print OUT $_;
		next;
	}
	chomp;
	@b=split /\t/,$_;
	$gene=$b[7];
	@c=split/\|/,$gene;
	
	foreach $i(@c){
		if (exists $h{$i}){
			$i=$i."|".$h{$i}.";";
		}
	}
	$d=join "",@c;
	print OUT "$b[0]\t$b[1]\t$b[2]\t$b[3]\t$b[4]\t$b[5]\t$b[6]\t$d\t$b[8]\t$b[9]\t$b[10]\n";
}
close EN;
close OUT;


 

 

 


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值