http://www.runoob.com/perl/perl-files.html
1.数据类型
标量 $ 开始, 如$a $b 是两个标量。
数组 @ 开始 , 如 @a @b 是两个数组。
哈希 % 开始 , %a %b 是两个哈希。
标量
$myfirst=123;
数组
@arr=(1,2,3)
哈希
%h=('a'=>1,'b'=>2)
2.数组操作
# 定义数组
@sites = qw(google taobao runoob facebook);
数组大小
@array = (1,2,3);
$array[50] = 4;
$size = @array;
$max_index = $#array;
print "数组大小: $size\n";
print "最大索引: $max_index\n";
$size = @array
# 在数组结尾添加一个元素
push(@sites, "baidu");
# 在数组开头添加一个元素
unshift(@sites, "weibo");
# 删除数组末尾的元素
pop(@sites);
# 移除数组开头的元素
shift(@sites);
#切割
@sites2 = @sites[3,4,5];
#替换
splice(@nums, 5, 5, 21..25);
# 字符串转为数组
@test = split('', $var_test);
# 数组转为字符串
$string1 = join( '-', @string );
哈希
%data = ('google'=>'google.com', 'runoob'=>'runoob.com', 'taobao'=>'taobao.com');
#访问
$data{'google'}
#读取
@data{'google','runoob'}
#读取键
@names = keys %data
$names[0]
#读取值
@urls = values %data
$urls[0]
# 添加元素
$data{'facebook'} = 'facebook.com';
检测元素是否存在
[root@bogon bigdata]# cat perl_test.pl
#!/usr/bin/perl
print "检测元素是否存在";
%data = ('google'=>'www.google.com','baidu'=>'www.baidu.com');
if( exists( $data{'google'} ) ){
print "$data{'google'}\n";
}
else
{
print "不存在\!\n";
}
[root@bogon bigdata]#
3.条件语句
#!/usr/bin/perl
use Switch;
$var = 10;
@array = (10, 20, 30);
%hash = ('key1' => 10, 'key2' => 20);
switch($var){
case 10 { print "数字 10\n" }
case "a" { print "字符串 a" }
case [1..10,42] { print "数字在列表中" }
case (\@array) { print "数字在数组中" }
case (\%hash) { print "在哈希中" }
else { print "没有匹配的条件" }
}
4.循环
# 执行 for 循环
for( $a = 0; $a < 10; $a = $a + 1 ){
print "a 的值为: $a\n";
}
@list = (2, 12, 36, 42, 51);
# 执行foreach 循环
foreach $a (@list){
print "a 的值为: $a\n";
}
# 执行 while 循环
while( $a < 20 ){
printf "a 的值为 : $a\n";
$a = $a + 1;
}
5.时间处理
Perl中处理时间的函数有如下几种:
1、time() 函数:返回从1970年1月1日起累计的秒数
2、localtime() 函数:获取本地时区时间
3、gmtime() 函数: 获取格林威治时间
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
printf("格式化时间:HH:MM:SS\n");
printf("%02d:%02d:%02d", $hour, $min, $sec);
#时间格式化
#!/usr/bin/perl
use POSIX qw(strftime);
$datestring = strftime "%Y-%m-%d %H:%M:%S", localtime;
printf("时间日期 - $datestring\n");
# GMT 格式化时间日期
$datestring = strftime "%Y-%m-%d %H:%M:%S", gmtime;
printf("时间日期 - $datestring\n");
6.子函数
sub function_name {
# body...
}
函数:my为私有变量
sub PintHash{
my (%hash) =@_;
foreach my $key (keys %hash){
my $value = $hash{$key};
print "$key :$value\n";
}
}
%hash = ('name'=>'a','age'=>3)
PrintHash(%hash)
静态变量state,类似static
#注1:state仅能创建闭合作用域为子程序内部的变量。
#注2:state是从Perl 5.9.4开始引入的,所以使用前必须加上 use。
#注3:state可以声明标量、数组、哈希。但在声明数组和哈希时,不能对其初始化(至少Perl 5.14不支持)。
#!/usr/bin/perl
use feature 'state';
sub PrintCount{
state $count = 0; # 初始化变量
print "counter 值为:$count\n";
$count++;
}
for (1..5){
PrintCount();
}
7.Perl 引用 ref()
$var = 10;
$r = \$var;
print "r 的引用类型 : ", ref($r), "\n";
@var = (1, 2, 3);
$r = \@var;
print "r 的引用类型 : ", ref($r), "\n";
%var = ('key1' => 10, 'key2' => 20);
$r = \%var;
print "r 的引用类型 : ", ref($r), "\n";
引用函数
#!/usr/bin/perl
# 函数定义
sub PrintHash{
my (%hash) = @_;
foreach $item (%hash){
print "元素 : $item\n";
}
}
%hash = ('name' => 'runoob', 'age' => 3);
# 创建函数的引用
$cref = \&PrintHash;
# 使用引用调用函数
&$cref(%hash);
8.格式化输出
#!/usr/bin/perl
#默认情况下函数write将结果输出到标准输出文件STDOUT,我们也可以使它将结果输出到任意其它的文件中
if (open(MYFILE, ">tmp")) {
$~ = "MYFORMAT";
write MYFILE; # 含文件变量的输出,此时会打印与变量同名的格式,即MYFILE。$~里指定的值被忽略。
format MYFILE = # 与文件变量同名
=================================
输入到文件中
=================================
.
close MYFILE;
}
#使用select改变默认文件变量时,它返回当前默认文件变量的内部表示,这样我们就可以创建子程序,按自己的想法输出,又不影响程序的其它部分
#!/usr/bin/perl
if (open(MYFILE, ">>tmp")) {
select (MYFILE); # 使得默认文件变量的打印输出到MYFILE中
$~ = "OTHER";
write; # 默认文件变量,打印到select指定的文件中,必使用$~指定的格式 OTHER
format OTHER =
=================================
使用定义的格式输入到文件中
=================================
.
close MYFILE;
}
9.文件操作
=pod 注释
Perl 使用一种叫做文件句柄类型的变量来操作文件。
从文件读取或者写入数据需要使用文件句柄。
文件句柄(file handle)是一个I/O连接的名称。
Perl提供了三种文件句柄:STDIN,STDOUT,STDERR,分别代表标准输入、标准输出和标准出错输出。
=cut
Perl 中打开文件可以使用以下方式:
open FILEHANDLE, EXPR
open FILEHANDLE
sysopen FILEHANDLE, FILENAME, MODE, PERMS
sysopen FILEHANDLE, FILENAME, MODE
=pod参数说明:
FILEHANDLE:文件句柄,用于存放一个文件唯一标识符。
EXPR:文件名及文件访问类型组成的表达式。
MODE:文件访问类型。
PERMS:访问权限位(permission bits)。
=cut
open(DATA,"<file_name") or die "file_name 无法打开,$!";
=pod
<以只读方式打开文件,>表示写入方式。
如果你需要以读写方式打开文件,可以在 > 或 < 字符前添加 + 号:
=cut
open(DATA, "+<file.txt"); or die "file.txt 文件无法打开, $!";
sysopen(DATA, "file.txt", O_RDWR|O_TRUNC );#在更新文件前清空文件
#关闭文件
close(DATA) || die "无法关闭文件";
#使用 <FILEHANDLE> 操作符时,它会返回文件句柄中每一行的列表,例如我们可以导入所有的行到数组中
#!/usr/bin/perl
[root@bogon bigdata]# cat import_perl.pl
#!/usr/bin/perl
open(DATA,"<import.txt") || die "无法打开文件";
@lines = <DATA>;
print @lines;
close(DATA);
[root@bogon bigdata]#
文件拷贝
#!/usr/bin/perl
# 只读方式打开文件
open(DATA1, "<file1.txt");
# 打开新文件并写入
open(DATA2, ">file2.txt");
# 拷贝数据
while(<DATA1>)
{
print DATA2 $_;
}
close( DATA1 );
close( DATA2 );
显示目录
#!/usr/bin/perl
opendir (DIR, '.') or die "无法打开目录, $!";
while ($file = readdir DIR) {
print "$file\n";
}
closedir DIR;
#!/usr/bin/perl
opendir(DIR, '.') or die "无法打开目录, $!";
foreach (sort grep(/^.*\.c$/,readdir(DIR))){
print "$_\n";
}
closedir DIR;
#创建删除、切换目录
mkdir( $dir ) or die "无法创建 $dir 目录, $!";
rmdir( $dir ) or die "无法删除 $dir 目录, $!";
chdir( $dir ) or die "无法切换目录到 $dir , $!";
10.错误处理
#程序中变量 $! 返回了错误信息
exists($hash{value}) ? '存在' : '不存在';#三目
#die/warn函数
chdir('/etc') || warn "无法切换目录";
chdir('/etc')||die "无法切换目录";
carp模块
=pod
在 Perl 脚本中,报告错误的常用方法是使用 warn() 或 die() 函数来报告或产生错误
而对于 Carp 模块,它可以对产生的消息提供额外级别的控制,尤其是在模块内部。
标准 Carp 模块提供了 warn() 和 die() 函数的替代方法,它们在提供错误定位方面提供更多信息,而且更加友好。当在模块中使用时,错误消息中包含模块名称和行号。
=cut
package T;
require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;
sub function_name {
# body...
confess "Error in module!";
}
1;
use T;
function_name();
11.特殊变量
foreach ('A','B','C'){
print $_;
print "\n";
}
12.正则表达式
=pod
Perl的正则表达式的三种形式,分别是匹配,替换和转化:
匹配:m//(还可以简写为//,略去m)
替换:s///
转化:tr///
这三种形式一般都和 =~ 或 !~ 搭配使用, =~ 表示相匹配,!~ 表示不匹配。
=cut
匹配 m//
if($bar =~ /run/){
#匹配run
}
=pod
perl处理完后会给匹配到的值存在三个特殊变量名:
$`: 匹配部分的前一部分字符串
$&: 匹配的字符串
$': 还没有匹配的剩余字符串
=cut
#!/usr/bin/perl
$string = "welcome to runoob site.";
$string =~ m/run/;#或$string =~ /run/;
print "匹配前的字符串: $`\n";
print "匹配的字符串: $&\n";
print "匹配后的字符串: $'\n";
替换 s/// s/PATTERN/REPLACEMENT/;
$string = "welcome to google site";
$string =~ s/google/runoob/;#google替换为runoob
转化:tr///
$string = 'welcome to runoob site';
$string =~ tr/a-z/A-Z/;
$string =~ tr/\d/ /c;#所有非数字转换成空格
$string =~ tr/\t //d;#删除所有Tab、空格
$string =~ tr/0-9/ /cs;#把数字间的其它字符替换为一个空格
12.socket编程
=pod
创建服务端
使用 socket 函数来创建 socket服务。
使用 bind 函数绑定端口。
使用 listen 函数监听端口。
使用 accept 函数接收客户端请求。
创建客户端
使用 socket 函数来创建 socket 服务。
使用 connect 函数连接到 socket 服务端。
=cut
服务端。
use socket
socket(SOCKET,PF_INEF,SOCKET_STREAM,(getprotobyname('tcp'))[2]);
#!/usr/bin/perl -w
# Filename : server.pl
use strict;
use Socket;
# 使用端口 7890 作为默认值
my $port = shift || 7890;
my $proto = getprotobyname('tcp');
my $server = "localhost"; # 设置本地地址
# 创建 socket, 端口可重复使用,创建多个连接
socket(SOCKET, PF_INET, SOCK_STREAM, $proto)
or die "无法打开 socket $!\n";
setsockopt(SOCKET, SOL_SOCKET, SO_REUSEADDR, 1)
or die "无法设置 SO_REUSEADDR $!\n";
# 绑定端口并监听
bind( SOCKET, pack_sockaddr_in($port, inet_aton($server)))
or die "无法绑定端口 $port! \n";
listen(SOCKET, 5) or die "listen: $!";
print "访问启动:$port\n";
# 接收请求
my $client_addr;
while ($client_addr = accept(NEW_SOCKET, SOCKET)) {
# send them a message, close connection
my $name = gethostbyaddr($client_addr, AF_INET );
print NEW_SOCKET "我是来自服务端的信息";
print "Connection recieved from $name\n";
close NEW_SOCKET;
}
$ perl sever.pl
客户端
#!/usr/bin/perl -w
# Filename : client.pl
use strict;
use Socket;
# 初始化地址与端口
my $host = shift || 'localhost';
my $port = shift || 7890;
my $server = "localhost"; # 主机地址
# 创建 socket 并连接
socket(SOCKET,PF_INET,SOCK_STREAM,(getprotobyname('tcp'))[2])
or die "无法创建 socket $!\n";
connect( SOCKET, pack_sockaddr_in($port, inet_aton($server)))
or die "无法连接:port $port! \n";
my $line;
while ($line = <SOCKET>) {
print "$line\n";
}
close SOCKET or die "close: $!";
$ perl client.pl
13.面向对象
=pod
创建一个类的实例 (对象) 我们需要定义一个构造函数,大多数程序使用类名作为构造函数,Perl 中可以使用任何名字。
你可以使用多种 Perl 的变量作为 Perl 的对象。大多数情况下我们会使用引用数组或哈希。
接下来我们为 Person 类创建一个构造函数,使用了 Perl 的哈希引用。
在创建对象时,你需要提供一个构造函数,它是一个子程序,返回对象的引用。
=cut
#!/usr/bin/perl
package Person;
sub new
{
my $class = shift;
my $self = {
_firstName => shift,
_lastName => shift,
_ssn => shift,
};
# 输出用户信息
print "名字:$self->{_firstName}\n";
print "姓氏:$self->{_lastName}\n";
print "编号:$self->{_ssn}\n";
bless $self, $class;
return $self;
}
sub setFirstName {
my ( $self, $firstName ) = @_;
$self->{_firstName} = $firstName if defined($firstName);
return $self->{_firstName};
}
sub getFirstName {
my( $self ) = @_;
return $self->{_firstName};
}
1;
#!/usr/bin/perl
use Person;
$object = new Person( "小明", "王", 23234345);
# 获取姓名
$firstName = $object->getFirstName();
print "设置前姓名为 : $firstName\n";
# 使用辅助函数设置姓名
$object->setFirstName( "小强" );
# 通过辅助函数获取姓名
$firstName = $object->getFirstName();
print "设置后姓名为 : $firstName\n";
继承 @ISA
package Employee;
use Person;
use strict;
our @ISA = qw(Person);
sub new {
# body...
my ($class) = @_;
my $self = $class->SUPER::new($_[1],$_[2],$_[3]);
$self->{_id} = undef;
$self->{_title} = undef;
bless $self,$class;
return $self;
}
sub getFirstName {
# body...
my ($self) = @_;
return $self->{_firstName};
}
sub setLastName {
# body...
my($self,$_lastName) = @_;
$self->{_lastName} = $_lastName if defined($_lastName);
return $self->{_lastName};
}
14.DBI
#!/usr/bin/perl -w
use strict;
use DBI;
my $host = "localhost"; # 主机地址
my $driver = "mysql"; # 接口类型 默认为 localhost
my $database = "RUNOOB"; # 数据库
# 驱动程序对象的句柄
my $dsn = "DBI:$driver:database=$database:$host";
my $userid = "root"; # 数据库用户名
my $password = "123456"; # 数据库密码
# 连接数据库
my $dbh = DBI->connect($dsn, $userid, $password ) or die $DBI::errstr;
my $sth = $dbh->prepare("SELECT * FROM Websites"); # 预处理 SQL 语句
$sth->execute(); # 执行 SQL 操作
# 注释这部分使用的是绑定值操作
# $alexa = 20;
# my $sth = $dbh->prepare("SELECT name, url
# FROM Websites
# WHERE alexa > ?");
# $sth->execute( $alexa ) or die $DBI::errstr;
# 循环输出所有数据
while ( my @row = $sth->fetchrow_array() )
{
print join('\t', @row)."\n";
}
$sth->finish();
$dbh->disconnect();
15.通用网关接口CGI
#!/usr/bin/perl
local ($buffer, @pairs, $pair, $name, $value, %FORM);
# 读取信息
$ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;
if ($ENV{'REQUEST_METHOD'} eq "POST")
{
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
}else {
$buffer = $ENV{'QUERY_STRING'};
}
# 读取 name/value 对信息
@pairs = split(/&/, $buffer);
foreach $pair (@pairs)
{
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%(..)/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
$text_content = $FORM{textcontent};
print "Content-type:text/html\r\n\r\n";
print "<html>";
print "<head>";
print '<meta charset="utf-8">';
print '<title>菜鸟教程(runoob.com)</title>';
print "</head>";
print "<body>";
print "<h2>输入的文本内容为:$text_content</h2>";
print "</body>";
print "</html>";
1;
1.数据类型
标量 $ 开始, 如$a $b 是两个标量。
数组 @ 开始 , 如 @a @b 是两个数组。
哈希 % 开始 , %a %b 是两个哈希。
标量
$myfirst=123;
数组
@arr=(1,2,3)
哈希
%h=('a'=>1,'b'=>2)
2.数组操作
# 定义数组
@sites = qw(google taobao runoob facebook);
数组大小
@array = (1,2,3);
$array[50] = 4;
$size = @array;
$max_index = $#array;
print "数组大小: $size\n";
print "最大索引: $max_index\n";
$size = @array
# 在数组结尾添加一个元素
push(@sites, "baidu");
# 在数组开头添加一个元素
unshift(@sites, "weibo");
# 删除数组末尾的元素
pop(@sites);
# 移除数组开头的元素
shift(@sites);
#切割
@sites2 = @sites[3,4,5];
#替换
splice(@nums, 5, 5, 21..25);
# 字符串转为数组
@test = split('', $var_test);
# 数组转为字符串
$string1 = join( '-', @string );
哈希
%data = ('google'=>'google.com', 'runoob'=>'runoob.com', 'taobao'=>'taobao.com');
#访问
$data{'google'}
#读取
@data{'google','runoob'}
#读取键
@names = keys %data
$names[0]
#读取值
@urls = values %data
$urls[0]
# 添加元素
$data{'facebook'} = 'facebook.com';
检测元素是否存在
[root@bogon bigdata]# cat perl_test.pl
#!/usr/bin/perl
print "检测元素是否存在";
%data = ('google'=>'www.google.com','baidu'=>'www.baidu.com');
if( exists( $data{'google'} ) ){
print "$data{'google'}\n";
}
else
{
print "不存在\!\n";
}
[root@bogon bigdata]#
3.条件语句
#!/usr/bin/perl
use Switch;
$var = 10;
@array = (10, 20, 30);
%hash = ('key1' => 10, 'key2' => 20);
switch($var){
case 10 { print "数字 10\n" }
case "a" { print "字符串 a" }
case [1..10,42] { print "数字在列表中" }
case (\@array) { print "数字在数组中" }
case (\%hash) { print "在哈希中" }
else { print "没有匹配的条件" }
}
4.循环
# 执行 for 循环
for( $a = 0; $a < 10; $a = $a + 1 ){
print "a 的值为: $a\n";
}
@list = (2, 12, 36, 42, 51);
# 执行foreach 循环
foreach $a (@list){
print "a 的值为: $a\n";
}
# 执行 while 循环
while( $a < 20 ){
printf "a 的值为 : $a\n";
$a = $a + 1;
}
5.时间处理
Perl中处理时间的函数有如下几种:
1、time() 函数:返回从1970年1月1日起累计的秒数
2、localtime() 函数:获取本地时区时间
3、gmtime() 函数: 获取格林威治时间
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
printf("格式化时间:HH:MM:SS\n");
printf("%02d:%02d:%02d", $hour, $min, $sec);
#时间格式化
#!/usr/bin/perl
use POSIX qw(strftime);
$datestring = strftime "%Y-%m-%d %H:%M:%S", localtime;
printf("时间日期 - $datestring\n");
# GMT 格式化时间日期
$datestring = strftime "%Y-%m-%d %H:%M:%S", gmtime;
printf("时间日期 - $datestring\n");
6.子函数
sub function_name {
# body...
}
函数:my为私有变量
sub PintHash{
my (%hash) =@_;
foreach my $key (keys %hash){
my $value = $hash{$key};
print "$key :$value\n";
}
}
%hash = ('name'=>'a','age'=>3)
PrintHash(%hash)
静态变量state,类似static
#注1:state仅能创建闭合作用域为子程序内部的变量。
#注2:state是从Perl 5.9.4开始引入的,所以使用前必须加上 use。
#注3:state可以声明标量、数组、哈希。但在声明数组和哈希时,不能对其初始化(至少Perl 5.14不支持)。
#!/usr/bin/perl
use feature 'state';
sub PrintCount{
state $count = 0; # 初始化变量
print "counter 值为:$count\n";
$count++;
}
for (1..5){
PrintCount();
}
7.Perl 引用 ref()
$var = 10;
$r = \$var;
print "r 的引用类型 : ", ref($r), "\n";
@var = (1, 2, 3);
$r = \@var;
print "r 的引用类型 : ", ref($r), "\n";
%var = ('key1' => 10, 'key2' => 20);
$r = \%var;
print "r 的引用类型 : ", ref($r), "\n";
引用函数
#!/usr/bin/perl
# 函数定义
sub PrintHash{
my (%hash) = @_;
foreach $item (%hash){
print "元素 : $item\n";
}
}
%hash = ('name' => 'runoob', 'age' => 3);
# 创建函数的引用
$cref = \&PrintHash;
# 使用引用调用函数
&$cref(%hash);
8.格式化输出
#!/usr/bin/perl
#默认情况下函数write将结果输出到标准输出文件STDOUT,我们也可以使它将结果输出到任意其它的文件中
if (open(MYFILE, ">tmp")) {
$~ = "MYFORMAT";
write MYFILE; # 含文件变量的输出,此时会打印与变量同名的格式,即MYFILE。$~里指定的值被忽略。
format MYFILE = # 与文件变量同名
=================================
输入到文件中
=================================
.
close MYFILE;
}
#使用select改变默认文件变量时,它返回当前默认文件变量的内部表示,这样我们就可以创建子程序,按自己的想法输出,又不影响程序的其它部分
#!/usr/bin/perl
if (open(MYFILE, ">>tmp")) {
select (MYFILE); # 使得默认文件变量的打印输出到MYFILE中
$~ = "OTHER";
write; # 默认文件变量,打印到select指定的文件中,必使用$~指定的格式 OTHER
format OTHER =
=================================
使用定义的格式输入到文件中
=================================
.
close MYFILE;
}
9.文件操作
=pod 注释
Perl 使用一种叫做文件句柄类型的变量来操作文件。
从文件读取或者写入数据需要使用文件句柄。
文件句柄(file handle)是一个I/O连接的名称。
Perl提供了三种文件句柄:STDIN,STDOUT,STDERR,分别代表标准输入、标准输出和标准出错输出。
=cut
Perl 中打开文件可以使用以下方式:
open FILEHANDLE, EXPR
open FILEHANDLE
sysopen FILEHANDLE, FILENAME, MODE, PERMS
sysopen FILEHANDLE, FILENAME, MODE
=pod参数说明:
FILEHANDLE:文件句柄,用于存放一个文件唯一标识符。
EXPR:文件名及文件访问类型组成的表达式。
MODE:文件访问类型。
PERMS:访问权限位(permission bits)。
=cut
open(DATA,"<file_name") or die "file_name 无法打开,$!";
=pod
<以只读方式打开文件,>表示写入方式。
如果你需要以读写方式打开文件,可以在 > 或 < 字符前添加 + 号:
=cut
open(DATA, "+<file.txt"); or die "file.txt 文件无法打开, $!";
sysopen(DATA, "file.txt", O_RDWR|O_TRUNC );#在更新文件前清空文件
#关闭文件
close(DATA) || die "无法关闭文件";
#使用 <FILEHANDLE> 操作符时,它会返回文件句柄中每一行的列表,例如我们可以导入所有的行到数组中
#!/usr/bin/perl
[root@bogon bigdata]# cat import_perl.pl
#!/usr/bin/perl
open(DATA,"<import.txt") || die "无法打开文件";
@lines = <DATA>;
print @lines;
close(DATA);
[root@bogon bigdata]#
文件拷贝
#!/usr/bin/perl
# 只读方式打开文件
open(DATA1, "<file1.txt");
# 打开新文件并写入
open(DATA2, ">file2.txt");
# 拷贝数据
while(<DATA1>)
{
print DATA2 $_;
}
close( DATA1 );
close( DATA2 );
显示目录
#!/usr/bin/perl
opendir (DIR, '.') or die "无法打开目录, $!";
while ($file = readdir DIR) {
print "$file\n";
}
closedir DIR;
#!/usr/bin/perl
opendir(DIR, '.') or die "无法打开目录, $!";
foreach (sort grep(/^.*\.c$/,readdir(DIR))){
print "$_\n";
}
closedir DIR;
#创建删除、切换目录
mkdir( $dir ) or die "无法创建 $dir 目录, $!";
rmdir( $dir ) or die "无法删除 $dir 目录, $!";
chdir( $dir ) or die "无法切换目录到 $dir , $!";
10.错误处理
#程序中变量 $! 返回了错误信息
exists($hash{value}) ? '存在' : '不存在';#三目
#die/warn函数
chdir('/etc') || warn "无法切换目录";
chdir('/etc')||die "无法切换目录";
carp模块
=pod
在 Perl 脚本中,报告错误的常用方法是使用 warn() 或 die() 函数来报告或产生错误
而对于 Carp 模块,它可以对产生的消息提供额外级别的控制,尤其是在模块内部。
标准 Carp 模块提供了 warn() 和 die() 函数的替代方法,它们在提供错误定位方面提供更多信息,而且更加友好。当在模块中使用时,错误消息中包含模块名称和行号。
=cut
package T;
require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;
sub function_name {
# body...
confess "Error in module!";
}
1;
use T;
function_name();
11.特殊变量
foreach ('A','B','C'){
print $_;
print "\n";
}
12.正则表达式
=pod
Perl的正则表达式的三种形式,分别是匹配,替换和转化:
匹配:m//(还可以简写为//,略去m)
替换:s///
转化:tr///
这三种形式一般都和 =~ 或 !~ 搭配使用, =~ 表示相匹配,!~ 表示不匹配。
=cut
匹配 m//
if($bar =~ /run/){
#匹配run
}
=pod
perl处理完后会给匹配到的值存在三个特殊变量名:
$`: 匹配部分的前一部分字符串
$&: 匹配的字符串
$': 还没有匹配的剩余字符串
=cut
#!/usr/bin/perl
$string = "welcome to runoob site.";
$string =~ m/run/;#或$string =~ /run/;
print "匹配前的字符串: $`\n";
print "匹配的字符串: $&\n";
print "匹配后的字符串: $'\n";
替换 s/// s/PATTERN/REPLACEMENT/;
$string = "welcome to google site";
$string =~ s/google/runoob/;#google替换为runoob
转化:tr///
$string = 'welcome to runoob site';
$string =~ tr/a-z/A-Z/;
$string =~ tr/\d/ /c;#所有非数字转换成空格
$string =~ tr/\t //d;#删除所有Tab、空格
$string =~ tr/0-9/ /cs;#把数字间的其它字符替换为一个空格
12.socket编程
=pod
创建服务端
使用 socket 函数来创建 socket服务。
使用 bind 函数绑定端口。
使用 listen 函数监听端口。
使用 accept 函数接收客户端请求。
创建客户端
使用 socket 函数来创建 socket 服务。
使用 connect 函数连接到 socket 服务端。
=cut
服务端。
use socket
socket(SOCKET,PF_INEF,SOCKET_STREAM,(getprotobyname('tcp'))[2]);
#!/usr/bin/perl -w
# Filename : server.pl
use strict;
use Socket;
# 使用端口 7890 作为默认值
my $port = shift || 7890;
my $proto = getprotobyname('tcp');
my $server = "localhost"; # 设置本地地址
# 创建 socket, 端口可重复使用,创建多个连接
socket(SOCKET, PF_INET, SOCK_STREAM, $proto)
or die "无法打开 socket $!\n";
setsockopt(SOCKET, SOL_SOCKET, SO_REUSEADDR, 1)
or die "无法设置 SO_REUSEADDR $!\n";
# 绑定端口并监听
bind( SOCKET, pack_sockaddr_in($port, inet_aton($server)))
or die "无法绑定端口 $port! \n";
listen(SOCKET, 5) or die "listen: $!";
print "访问启动:$port\n";
# 接收请求
my $client_addr;
while ($client_addr = accept(NEW_SOCKET, SOCKET)) {
# send them a message, close connection
my $name = gethostbyaddr($client_addr, AF_INET );
print NEW_SOCKET "我是来自服务端的信息";
print "Connection recieved from $name\n";
close NEW_SOCKET;
}
$ perl sever.pl
客户端
#!/usr/bin/perl -w
# Filename : client.pl
use strict;
use Socket;
# 初始化地址与端口
my $host = shift || 'localhost';
my $port = shift || 7890;
my $server = "localhost"; # 主机地址
# 创建 socket 并连接
socket(SOCKET,PF_INET,SOCK_STREAM,(getprotobyname('tcp'))[2])
or die "无法创建 socket $!\n";
connect( SOCKET, pack_sockaddr_in($port, inet_aton($server)))
or die "无法连接:port $port! \n";
my $line;
while ($line = <SOCKET>) {
print "$line\n";
}
close SOCKET or die "close: $!";
$ perl client.pl
13.面向对象
=pod
创建一个类的实例 (对象) 我们需要定义一个构造函数,大多数程序使用类名作为构造函数,Perl 中可以使用任何名字。
你可以使用多种 Perl 的变量作为 Perl 的对象。大多数情况下我们会使用引用数组或哈希。
接下来我们为 Person 类创建一个构造函数,使用了 Perl 的哈希引用。
在创建对象时,你需要提供一个构造函数,它是一个子程序,返回对象的引用。
=cut
#!/usr/bin/perl
package Person;
sub new
{
my $class = shift;
my $self = {
_firstName => shift,
_lastName => shift,
_ssn => shift,
};
# 输出用户信息
print "名字:$self->{_firstName}\n";
print "姓氏:$self->{_lastName}\n";
print "编号:$self->{_ssn}\n";
bless $self, $class;
return $self;
}
sub setFirstName {
my ( $self, $firstName ) = @_;
$self->{_firstName} = $firstName if defined($firstName);
return $self->{_firstName};
}
sub getFirstName {
my( $self ) = @_;
return $self->{_firstName};
}
1;
#!/usr/bin/perl
use Person;
$object = new Person( "小明", "王", 23234345);
# 获取姓名
$firstName = $object->getFirstName();
print "设置前姓名为 : $firstName\n";
# 使用辅助函数设置姓名
$object->setFirstName( "小强" );
# 通过辅助函数获取姓名
$firstName = $object->getFirstName();
print "设置后姓名为 : $firstName\n";
继承 @ISA
package Employee;
use Person;
use strict;
our @ISA = qw(Person);
sub new {
# body...
my ($class) = @_;
my $self = $class->SUPER::new($_[1],$_[2],$_[3]);
$self->{_id} = undef;
$self->{_title} = undef;
bless $self,$class;
return $self;
}
sub getFirstName {
# body...
my ($self) = @_;
return $self->{_firstName};
}
sub setLastName {
# body...
my($self,$_lastName) = @_;
$self->{_lastName} = $_lastName if defined($_lastName);
return $self->{_lastName};
}
14.DBI
#!/usr/bin/perl -w
use strict;
use DBI;
my $host = "localhost"; # 主机地址
my $driver = "mysql"; # 接口类型 默认为 localhost
my $database = "RUNOOB"; # 数据库
# 驱动程序对象的句柄
my $dsn = "DBI:$driver:database=$database:$host";
my $userid = "root"; # 数据库用户名
my $password = "123456"; # 数据库密码
# 连接数据库
my $dbh = DBI->connect($dsn, $userid, $password ) or die $DBI::errstr;
my $sth = $dbh->prepare("SELECT * FROM Websites"); # 预处理 SQL 语句
$sth->execute(); # 执行 SQL 操作
# 注释这部分使用的是绑定值操作
# $alexa = 20;
# my $sth = $dbh->prepare("SELECT name, url
# FROM Websites
# WHERE alexa > ?");
# $sth->execute( $alexa ) or die $DBI::errstr;
# 循环输出所有数据
while ( my @row = $sth->fetchrow_array() )
{
print join('\t', @row)."\n";
}
$sth->finish();
$dbh->disconnect();
15.通用网关接口CGI
#!/usr/bin/perl
local ($buffer, @pairs, $pair, $name, $value, %FORM);
# 读取信息
$ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;
if ($ENV{'REQUEST_METHOD'} eq "POST")
{
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
}else {
$buffer = $ENV{'QUERY_STRING'};
}
# 读取 name/value 对信息
@pairs = split(/&/, $buffer);
foreach $pair (@pairs)
{
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%(..)/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
$text_content = $FORM{textcontent};
print "Content-type:text/html\r\n\r\n";
print "<html>";
print "<head>";
print '<meta charset="utf-8">';
print '<title>菜鸟教程(runoob.com)</title>';
print "</head>";
print "<body>";
print "<h2>输入的文本内容为:$text_content</h2>";
print "</body>";
print "</html>";
1;