Overview
最近经常需要使用到Perl
处理文件,因此在此记录一下经常使用到的Perl
知识。
1. Perl
脚本中接受命令行参数
很多时候我们编写一个Perl
脚本,都是用来处理一个文件,输出为另一个文件,例如,脚本file_converter.pl
将input.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_init
和defined($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;