use strict; #报错语句
use warnings;
open (FA,"file") or die $!; #打开文件句柄
open (FB,">file1") or die $!;
while (){
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 = ){
chomp($test) ;
print $test;
}
close FILE;
输入的方式:
键盘输入:$line=
钻石输入符:<>
调用参数:@ARGV
输出的方式:
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 =){
$test =~/^\n/;
$i++;
}
print $test;
}
close FILE;
use strict;
use warnings;
open (FA,"file") or die $!;
open (FB,">file2") or die $!;
my @d=;
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是求个数的函数,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 = );
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= );
print "$name working time is: $hash{$name} .\n";
2.11. 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 = ){
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的信息。输出内容及格式为ID、parent、protein_id和product(结果如图所示)。(20分)
#!/usr/bin/perl
use strict;
use warnings;
open IN, "<", $ARGV[0];
while (my $line = ){
next,if($line =~ /^#/);
if($line =~ /ID=(.*?);Parent=(.*?);.*?product=(.*?);.*?protein_id=(.*?);/){
print $1,"\t",$2,"\t",$3,"\t",$4,"\n";
}
}
close IN;
__END__
思路:首先要去除注释信息,所以匹配到#就删除,注意此处用的.*?可以匹配任意多字符,用()来捕捉信息,以分号为界
2.3从3.test序列文件(第一个碱基T的位置记为1)中提取出gene0的碱基序列,已知gene0的起始位置是319,终止位置是1674。(15分)
#!/usr/bin/perl
use strict;
use warnings;
open IN, "<", $ARGV[0];
my $seq = ;
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 = ;
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 () {
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 = ){
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,"){
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,"){
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.add_annot.xls")||die "can not creat!";
while(){
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;