Overview
最近经常需要使用到Perl
处理文件,因此在此记录一下经常使用到的Perl
知识。
1. Perl
脚本中接受命令行参数
很多时候我们编写一个Perl
脚本,都是用来处理一个文件,输出为另一个文件,例如,脚本file_converter.pl
将input.txt
中的格式处理之后转化为另一种格式存储在output.txt
中,则通常我们的使用习惯是
1 | ./file_converter.pl input.txt output.txt |
在Perl
脚本中可以使用@ARGV
获取命令行的参数,上面的例子中,@ARGV
的值为2,使用$ARGV[0]
和$ARGV[1]
几个获取到这两个文件名字,示例如下:
1 2 3 4 5 6 | if (@ARGV != 2) { print "==Error: Please input the file you need to convert and the file name of the result\n"; } my $original_file_name = $ARGV[0]; my $output_file = $ARGV[1]; |
2. 判断要使用的变量是否已定义
or已赋值
在使用一个变量时,有时需要先判断这个变量是不是第一次被使用,这时我们通常可以选择定义此变量时只声明,不赋值。而在使用时,使用两种方式判断该变量是不是已经被赋值了。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | my $name_not_init; my $name="Gly"; if(!$name_not_init) { print "null\n" } else { print "not null\n"; } if(defined($name_not_init)) { print "defined\n"; } else { print "not defined\n"; } if(!$name) { print "null\n" } else { print "not null\n"; } if(defined($name)) { print "defined\n"; } else { print "not defined\n"; } |
运行结果为:
1 2 3 4 | null not defined not null defined |
即当一个变量只是被声明,未被赋值之前,都是未定义的,$name_not_init
和defined($name_not_init)
都为假。
但是,当对数组变量使用defined
时,会报一下诊断信息:
1 | defined(@array) is deprecated |
(D-废弃-反对-可选)通常defined对数组并没有作用,因为它只是检查一个未定义的标量值。可以使用刚才说的另一种方式:
1 2 3 4 | if (!@array) { #数组为空 } |
3. 获取数组长度
非常简单,直接将一个数组变量赋给一个普通变量或者使用scalar,示例如下:
1 2 | my $count_array = @line_texts; #method 1 my $count_array = scalar @line_texts; #method 2 |
4. 从网页获取数据
直接使用一段代码展示,该代码从http://www.uniprot.org/uniprot/P01282.fasta
处请求内容,这个网站是一个蛋白质序列信息查询网站,如果查询的ID信息存在,则返回该序列的信息,格式如下:
1 2 3 4 | #>sp|P01282|VIP_HUMAN VIP peptides OS=Homo sapiens GN=VIP PE=1 SV=1 MDTRNKAQLLVLLTLLSVLFSQTSAWPLYRAPSALRLGDRIPFEGANEPDQVSLKEDIDM LQNALAENDTPYYDVSRNARHADGVFTSDFSKLLGQLSAKKYLESLMGKRVSSNISEDPV PVKRHSDAVFTDNYTRLRKQMAVKKYLNSILNGKRSSEGESPDFPEELEK |
以上数据以每一行之后以空格结尾,第一行为序列描述信息,我们需要的是提取第一行数据之外的序列详细信息,并去掉每一行之后的空格,我们需要的是以下结果:
1 | MDTRNKAQLLVLLTLLSVLFSQTSAWPLYRAPSALRLGDRIPFEGANEPDQVSLKEDIDMLQNALAENDTPYYDVSRNARHADGVFTSDFSKLLGQLSAKKYLESLMGKRVSSNISEDPVPVKRHSDAVFTDNYTRLRKQMAVKKYLNSILNGKRSSEGESPDFPEELEK |
如果查询的ID信息不存在,则会返回一个包含Not found的网页,此时我们使用-
代替序列内容。
完整代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #!/usr/bin/perl -w #载入Web请求和解析所需要的模块 use LWP::UserAgent; use HTML::Element; use HTML::TreeBuilder; #需要请求内容的网页 my $url = "http://www.uniprot.org/uniprot/P01282.fasta"; my $root = new HTML::TreeBuilder; my $ua = LWP::UserAgent->new; #设置请求,这里使用的是GET请求,如果是POST参数,需要在$ua->request($req)之前设置一些参数,这里不展开 my $req = HTTP::Request->new('GET' => $url); #发送请求 my $res = $ua->request($req); #获得请求的网页内容,这里的网页内容是包含HTML代码的原生内容,需要自己抽取信息(不过这个网址恰好比较干净,比较方便获取) my $res_content= $res->content(); #使用$solved_web_result存储最终需要得到的内容 my $solved_web_result=""; #以换行符为分割,截断获得的网页内容,存在数组中 my @web_results=split(/\n/,$res_content); #去掉第一行的内容,并将剩下的内容合并起来 my $first_loop_count=0; foreach $web_line (@web_results) { if($first_loop_count!=0) { $solved_web_result=$solved_web_result.$web_line; } $first_loop_count++; } #如果查询的ID信息不存在,则使用-代替。 if ($solved_web_result=~m/not found/) { $solved_web_result="-"; } #最后加上换行符 $solved_web_result=$solved_web_result."\n"; print $solved_web_result; |