Overview

最近经常需要使用到Perl处理文件,因此在此记录一下经常使用到的Perl知识。

1. Perl脚本中接受命令行参数

很多时候我们编写一个Perl脚本,都是用来处理一个文件,输出为另一个文件,例如,脚本file_converter.plinput.txt中的格式处理之后转化为另一种格式存储在output.txt中,则通常我们的使用习惯是

./file_converter.pl input.txt output.txt

Perl脚本中可以使用@ARGV获取命令行的参数,上面的例子中,@ARGV的值为2,使用$ARGV[0]$ARGV[1]几个获取到这两个文件名字,示例如下:

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已赋值

在使用一个变量时,有时需要先判断这个变量是不是第一次被使用,这时我们通常可以选择定义此变量时只声明,不赋值。而在使用时,使用两种方式判断该变量是不是已经被赋值了。代码如下:

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";
}

运行结果为:

null
not defined
not null
defined

即当一个变量只是被声明,未被赋值之前,都是未定义的,$name_not_initdefined($name_not_init)都为假。
但是,当对数组变量使用defined时,会报一下诊断信息:

defined(@array) is deprecated

(D-废弃-反对-可选)通常defined对数组并没有作用,因为它只是检查一个未定义的标量值。可以使用刚才说的另一种方式:

if (!@array)
{
    #数组为空
}

3. 获取数组长度

非常简单,直接将一个数组变量赋给一个普通变量或者使用scalar,示例如下:

my $count_array = @line_texts; #method 1
my $count_array = scalar @line_texts; #method 2

4. 从网页获取数据

直接使用一段代码展示,该代码从http://www.uniprot.org/uniprot/P01282.fasta处请求内容,这个网站是一个蛋白质序列信息查询网站,如果查询的ID信息存在,则返回该序列的信息,格式如下:

#>sp|P01282|VIP_HUMAN VIP peptides OS=Homo sapiens GN=VIP     PE=1 SV=1
MDTRNKAQLLVLLTLLSVLFSQTSAWPLYRAPSALRLGDRIPFEGANEPDQVSLKEDIDM
LQNALAENDTPYYDVSRNARHADGVFTSDFSKLLGQLSAKKYLESLMGKRVSSNISEDPV
PVKRHSDAVFTDNYTRLRKQMAVKKYLNSILNGKRSSEGESPDFPEELEK

以上数据以每一行之后以空格结尾,第一行为序列描述信息,我们需要的是提取第一行数据之外的序列详细信息,并去掉每一行之后的空格,我们需要的是以下结果:

   MDTRNKAQLLVLLTLLSVLFSQTSAWPLYRAPSALRLGDRIPFEGANEPDQVSLKEDIDMLQNALAENDTPYYDVSRNARHADGVFTSDFSKLLGQLSAKKYLESLMGKRVSSNISEDPVPVKRHSDAVFTDNYTRLRKQMAVKKYLNSILNGKRSSEGESPDFPEELEK

如果查询的ID信息不存在,则会返回一个包含Not found的网页,此时我们使用-代替序列内容。
完整代码如下:

#!/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;