1、Perl 语言入门实战习题1、计算 FASTA 文件中每条序列的长度;输入文件,FASTA 格式:注:如果输入文件在 windows 下产生,在 Linux 系统下操作时,宜先用 dos2unix 处理:用法:dos2unix 输入文件输出文件:Perl 代码:#!/usr/bin/perl -wuse strict;unless (ARGV=2) # ARGV 传给脚本的命令行参数列表 die“Usage: perl $0 n“; # 当命令行参数不是 2 的时候输出使用说明my ($infile,$outfile) = ARGV; # 把命令行参数赋值给输入文件和输出文件open IN,$
2、infile | die“error: cant open infile: $infile“; # 打开输入文件句柄 INopen OUT,“$outfile“ | die$!; # 打开输出文件句柄 OUT$/=“; # 设置输入记录分隔符为”,并去除第一个”while ( my $seq = ) # 把序列 ID 行和序列赋值给$seqmy $id = $1 if($seq = /(S+)/); # 获取序列 IDchomp $seq; # 去掉末尾的”$seq = s/.+?n/; # 删除第一行$seq = s/s/g; # 删除序列中的空白字符my $len = length($se
3、q); # 计算序列长度print OUT “$idt$lenn“; # 输出结果到输出文件$/=“n“; # 把输入记录分隔符改为默认值close IN; # 关闭输入文件句柄close OUT; # 关闭输出文件句柄2、计算 FASTA 文件中每条序列的 GC 含量;输入文件同上,输出文件:Perl 代码:#!/usr/bin/perl -wuse strict;unless (ARGV=2) # ARGV 传给脚本的命令行参数列表 die“Usage: perl $0 n“;# 当命令行参数不是 2 的时候输出使用说明my ($infile,$outfile) = ARGV;# 把命令行
4、参数赋值给输入文件和输出文件open IN,$infile | die“error: cant open infile: $infile“;# 打开输入文件句柄 INopen OUT,“$outfile“ | die$!;# 打开输出文件句柄 OUT$/=“;# 设置输入记录分隔符为”,并去除第一个”while ()# $_=,把序列 ID 行和序列赋值给$_,$_= 可以省略不写my $id = $1 if(/(S+)/);# 获取序列 IDchomp; # 去掉末尾的 ”s/.+?n/;# 删除第一行s/s/g; # 删除序列中的空白字符my $GC = (tr/GC/GC/);#计算 G
5、 或 C 碱基个数my $AT = (tr/AT/AT/);#计算 A 或 T 碱基个数my $len = $GC + $AT;# 计算序列非 N 长度my $gc_cont = $len ? $GC / $len : 0; #计算 GC 含量,如果长度为 0,GC 含量算 0print OUT “$idt$gc_contn“; # 输出结果到输出文件$/=“n“;# 把输入记录分隔符改为默认值close IN; # 关闭输入文件句柄close OUT;# 关闭输出文件句柄3、求反相互补序列;输入文件同上,输出文件也是 FASTA 格式Perl 代码:#!/usr/bin/perl -wuse
6、 strict;unless (ARGV=2) # ARGV 传给脚本的命令行参数列表 die“Usage: perl $0 n“;# 当命令行参数不是 2 的时候输出使用说明my ($infile,$outfile) = ARGV;# 把命令行参数赋值给输入文件和输出文件open IN,$infile | die“error: cant open infile: $infile“;# 打开输入文件句柄 INopen OUT,“$outfile“ | die$!;# 打开输出文件句柄 OUT$/=“;# 设置输入记录分隔符为”,并去除第一个”while ()# $_=,把序列 ID 行和序列赋
7、值给$_,$_= 可以省略不写my $id = $1 if(/(S+)/);# 获取序列 IDchomp; # 去掉末尾的 ”s/.+?n/;# 删除第一行s/s/g; # 删除序列中的空白字符$_ = reverse $_; # 序列方向tr/ATCG/TAGC/; # 序列互补print OUT “$idn“,$_,“n“; # 输出结果到输出文件$/=“n“;# 把输入记录分隔符改为默认值close IN; # 关闭输入文件句柄close OUT;# 关闭输出文件句柄4、列表信息整合;输入列表 1:序列长度文件输入文件 2:序列测序覆盖深度文件输出文件:把上述两个列表的信息整合成一个列表
8、,并且最后一行给出汇总结果:Perl 代码#!/usr/bin/perl -wuse strict;(ARGV=3) | die“Usage: perl $0 n“;# 当命令行参数不是 3 的时候输出使用说明my ($infile1,$infile2,$outfile) = ARGV;# 把命令行参数赋值给输入文件 1、输入文件 2 和输出文件my %id_len; # 定义一个哈希open IN1,$infile1 | die$!; # 打开第一个文件句柄while()my ($id,$len) = split /s+/,$_; # split 函数用空白符号切割每一行的内容$id_len
9、$id = $len; # 哈希赋值:id = lengthclose IN1; # 关闭第一个文件句柄open IN2,$infile2 | die$!; # 打开第 2 个文件句柄open OUT,“$outfile“ | die$!; # 打开输出文件句柄my $tol_len = 0; # 定义总长度变量,并赋值为 0my $tol_depth = 0; # 定义总深度变量,并赋值为 0while ()my ($id,$depth) = split; # split 函数用空白符号切割每一行的内容my $len = $id_len$id; # 序列长度print OUT join(“t
10、“,$id,$len,$depth),“n“; # 输出整合信息到输出文件$tol_len += $len; # 长度累加$tol_depth += $len * $depth; # 深度累加 $tol_depth /= $tol_len; # 计算总体平均深度print OUT “Totalt$tol_lent$tol_depthn“; # 输出汇总结果到输出文件close IN2; # 关闭第二个输入文件句柄close OUT; # 关闭输出文件句柄5、串流程;Perl 在工作中常用于串流程,现有同事写了 3 个 perl 脚本分三步将输入文件,infile.txt 处理成最终的 fina
11、l.result:第 1 步:perl step1.pl infile.txt output1第 2 步:perl step2.pl infile.txt output2第 3 步:perl step3.pl output1 output2 final.result为提高工作效率,现需要写一个脚本使用 infile.txt 作为输入文件,直接得到 final.result,中间产生的文件结果不保留。#!/usr/bin/perl -wuse strict;unless (ARGV=2) # ARGV 传给脚本的命令行参数列表 die“Usage: perl $0 n“;# 当命令行参数不是 2 的时候输出使用说明my ($infile,$outfile) = ARGV;# 把命令行参数赋值给输入文件和输出文件my $temp_file = “temp.$”; # 临时文件,$为进程号,这样可以保证文件名字的唯一性system“perl step1.pl $infile $temp.1perl step2.pl $infle $temp.2perl step3.pl $temp.1 $temp.2 $outfilerm $temp.1 $temp.2”#使用 system 调用 3 个 perl 脚本进行处理