Perl学习笔记

该博客围绕Perl编程展开,介绍了磁盘空间使用通知、命令执行等功能。详细讲解了字符串、浮点数、操作符、列表、数组等基础知识,还涉及循环控制、子程序调用、参数传递等编程要点,以及预定义子程序、管道操作等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[最后修改时间:2005年2月5日]
1 notify the administrator regarding the FA disk space usage

#!/usr/bin/perl

 

# Purpose: This file will notify the administrator regarding the disk space usage.

 

open(INF,"df -k /usr/test/g/|");

 

while ($line = <INF>)                    

{

 

 if ($line=~m/.*/s+(/d+)/%/)            

 {

  # x is the disk space thershold- percentage of disk space usage 

  $x = $1;                             

 

   if ($x > 55)                     

   

   {

      open MAIL, "|mail  qqq/@email.tom.com";

      print MAIL "reached to $x% of space usage, please raise a s as soon as possible.";

 

 

close MAIL;

   }

 

  }

 

}

 

2 execute command

$OS_TYPE = ‘uname –r’;

 

3 string

PERL中,字符串的末尾并不含有隐含的NULL字符,NULL字符可以出现在串的任何位置。

反斜线可以取消变量替换

单引号字符串与双引号字符串有两个区别,一是没有变量替换功能,二是反斜线不支持转义字符,而只在包含单引号和反斜线时起作用。单引号另一个特性是可以跨多行

字符串和数值的互相转换:若字符串中含有非数字的字符,则从左起至第一个非数字的字符。

 

4 浮点数

指数的范围通常为-309+308

 

5 default value

PERL中,所有的简单变量都有缺省初始值:"",即空字符。

 

6 operators

**(乘幂):乘幂的基数不能为负

整数比较操作符:<=> 比较,返回 1, 0, or -1

0 - 两个值相等
1 - 第一个值大
-1 - 第二个值大

 

字符串比较操作符
lt 小于  
gt 大于  
eq 等于  
le 小于等于  
ge 大于等于  
ne 不等于

cmp 比较,返回 1, 0, or -1

 

不要将位与&用于负整数,因为PERL将会把它们转化为无符号数。

 

=作为子表达式
($a = $b) += 3;
等价于
$a = $b;
$a += 3;

 

PERL++可用于字符串,但当结尾字符为'z''Z''9'时进位

$stringvar = "AGZZZ";
$stringvar++; # $stringvar now contains "AHAAA"

$stringvar = "bc999";
$stringvar++; # $stringvar now contains "bd000"

 

--PERL将先将字符串转换为数字再进行自减
$stringvar = "abc";
$stringvar--; # $stringvar = -1 now

 

字符串联接: .
字符串重复:x

$fred = "Fred";
print (("Hello, " . $fred . "!n") x 2);
其结果为:
Hello, Fred!
Hello, Fred!

 

逗号操作符 :其前面的表达式先进行运算,如:
$var1 += 1, $var2 = $var1;
等价于
$var1 += 1;
$var2 = $var1;
使用此操作符的唯一理由是提高程序的可读性,将关系密切的两个表达式结合在一起,如:
$val = 26;
$result = (++$val, $val + 5); # $result = 32
注意如果此处没有括号则意义不同:
$val = 26;
$result = ++$val, $val + 5; # $result = 27

 

 

7 从标准输入(STDIN)给变量赋值
$var = <STDIN>;
@array = <STDIN>; # ^D为结束输入的符号

 

8 列表范围
(1..10) = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
(2, 5..7, 11) = (2, 5, 6, 7, 11)
(3..3) = (3)

用于实数
(2.1..5.3) = (2.1, 3.1 ,4.1, 5.1)
(4.5..1.6) = ()

用于字符串
("aaa".."aad") = ("aaa","aab", "aac", "aad")
@day_of_month = ("01".."31")

可包含变量或表达式
($var1..$var2+5)

 

9 数组的输出
(1) @array = (1, 2, 3);
print (@array, "n");
结果为:
123
(2) @array = (1, 2, 3);
print ("@arrayn");
结果为:
1 2 3

 

10 列表/数组的长度
当数组变量出现在预期简单变量出现的地方,则PERL解释器取其长度。
@array = (1, 2, 3);
$scalar = @array; # $scalar = 3,@array的长度
($scalar) = @array; # $scalar = 1,@array第一个元素的值
注:以数组的长度为循环次数可如下编程:
$count = 1;
while ($count <= @array) {
print ("element $count: $array[$count-1]n");
$count++;
}

 

11 子数组
@array = (1, 2, 3, 4, 5);
@subarray = @array[0,1]; # @subarray = (1, 2)
@subarray2 = @array[1..3]; # @subarray2 = (2,3,4)
@array[0,1] = ("string", 46); # @array =("string",46,3,4,5) now
@array[0..3] = (11, 22, 33, 44); # @array = (11,22,33,44,5) now
@array[1,2,3] = @array[3,2,4]; # @array = (11,44,33,5,5) now
@array[0..2] = @array[3,4]; # @array = (5,5,"",5,5) now
可以用子数组形式来交换元素:
@array[1,2] = @array[2,1];

 

12 有关数组的库函数
(1)sort--按字符顺序排序
@array = ("this", "is", "a","test");
@array2 = sort(@array); # @array2 = ("a","is", "test", "this")
@array = (70, 100, 8);
@array = sort(@array); # @array = (100, 70, 8) now

(2)reverse--反转数组
@array2 = reverse(@array);
@array2 = reverse sort (@array);

(3)chop--数组去尾
chop的意义是去掉STDIN(键盘)输入字符串时最后一个字符--换行符。而如果它作用到数组上,则将数组中每一个元素都做如此处理。
@list = ("rabbit", "12345","quartz");
chop (@list); # @list = ("rabbi", "1234","quart") now

(4)join/split--连接/拆分
join的第一个参数是连接所用的中间字符,其余则为待连接的字符数组。
$string = join(" ", "this", "is","a", "string"); # 结果为"this is a string"
@list = ("words","and");
$string = join("::", @list, "colons"); #结果为"words::and::colons"
@array = split(/::/,$string); # @array = ("words","and", "colons") now

 

13 针对列表(数组)每个元素的循环:foreach

语法为:
foreach localvar (listexpr) {
statement_block;
}

例:
foreach $word (@words) {
if ($word eq "the") {
print ("found the word 'the'n");
}
}

注:
(1)此处的循环变量localvar是个局部变量,如果在此之前它已有值,则循环后仍恢复该值。
(2)在循环中改变局部变量,相应的数组变量也会改变,如:
@list = (1, 2, 3, 4, 5);
foreach $temp (@list) {
if ($temp == 2) {
$temp = 20;
}
}
此时@list已变成了(1, 20, 3, 4, 5)

 

14 循环控制
退出循环为last,与C中的break作用相同;执行下一个循环为next,与C中的continue作用相同;PERL特有的一个命令是redo,其含义是重复此次循环,即循环变量不变,回到循环起始点,但要注意,redo命令在do循环中不起作用。

 

15 单行条件
语法为statement keyword condexpr。其中keyword可为ifunlesswhileuntil,如:
print ("This is zero.n") if ($var == 0);
print ("This is zero.n") unless ($var != 0);
print ("Not zero yet.n") while ($var-- > 0);
print ("Not zero yet.n") until ($var-- == 0);
虽然条件判断写在后面,但却是先执行的。

 

16 子程序调用
调用方法如下:
1、用&调用
&subname;
...
sub subname{
...
}
2、先定义后调用 ,可以省略&符号
sub subname{
...
}
...
subname;
3、前向引用 ,先定义子程序名,后面再定义子程序体
sub subname;
...
subname;
...
sub subname{
...
}
4、用do调用
do my_sub(1, 2, 3);等价于&my_sub(1, 2, 3);

 

17 子程序返回值
缺省的,子程序中最后一个语句的值将用作返回值。语句return (retval);也可以推出子程序并返回值retvalretval可以为列表。

 

18 局部变量

子程序中局部变量的定义有两种方法:mylocal。其区别是:my定义的变量只在该子程序中存在;而local定义的变量不存在于主程序中,但存在于该子程序和该子程序调用的子程序中(PERL4中没有my)。定义时可以给其赋值,如:
my($scalar) = 43;
local(@array) = (1, 2, 3);

 

19 子程序参数传递

1、形式
&sub1(&number1, $number2, $nubmer3);
...
sub sub1{
my($number1, $number2, $number3) = @_;
...
}
2、传送数组
&addlist (@mylist);
&addlist ("14", "6", "11");
&addlist ($value1, @sublist, $value2);
...
sub addlist {
my (@list) = @_;
...
}
参数为数组时,子程序只将它赋给一个数组变量。如
sub twolists {
my (@list1, @list2) = @_;
}
@list2必然为空。但简单变量和数组变量可以同时传递:
&twoargs(47, @mylist); # 47赋给$scalar@mylist赋给@list
&twoargs(@mylist); # @mylist的第一个元素赋给$scalar,其余的元素赋给@list
...
sub twoargs {
my ($scalar, @list) = @_;
...
}

 

20 用别名传递数组参数
1、用前面讲到的调用方法&my_sub(@array)将把数组@array的数据拷贝到子程序中的变量@_中,当数组很大时,将会花费较多的资源和时间,而用别名传递将不做这些工作,而对该数组直接操作。形式如:
@myarray = (1, 2, 3, 4, 5);
&my_sub(*myarray);
sub my_sub {
my (*subarray) = @_;
}

2、此方法类似于C语言中的传递数组的起始地址指针,但并不一样,在定义数组的别名之后,如果有同名的简单变量,则对该变量也是起作用的。如:
$foo = 26;
@foo = ("here's", "a", "list");
&testsub (*foo);
...
sub testsub {
local (*printarray) = @_;
...
$printarray = 61;
}
当子程序执行完,主程序中的$foo的值已经成了61,而不再是26了。

3、用别名的方法可以传递多个数组,如:
@array1 = (1, 2, 3);
@array2 = (4, 5, 6);
&two_array_sub (*array1, *array2);
sub two_array_sub {
my (*subarray1, *subarray2) = @_;
}
在该子程序中,subarray1array1的别名,subarray2array2的别名。

21 预定义的子程序

PERL5预定义了三个子程序,分别在特定的时间执行,它们是:BEGIN子程序在程序启动时被调用;END子程序在程序结束时被调用;AUTOLOAD子程序在找不到某个子程序时被调用。你可以自己定义它们,以在特定时间执行所需要的动作。如:
BEGIN {
print("Hi! Welcome to Perl!n");
}
AUTOLOAD{
print("subroutine $AUTOLOAD not foundn"); # 变量$AUTOLOAD即未找到的子程序名
print("arguments passed: @_n");
}
若同一个预定义子程序定义了多个,则BEGIN顺序执行,END逆序执行。

 

 

22 注意://bdef/可匹配$defghi,因为$并不被看作是单词的部分。

 

23 check all the failure possibilities by inspecting $? like this:

    if ($? == -1) {

        print "failed to execute: $!/n";

    }

    elsif ($? & 127) {

        printf "child died with signal %d, %s coredump/n",

            ($? & 127),  ($? & 128) ? 'with' : 'without';

    }

    else {

        printf "child exited with value %d/n", $? >> 8;

    }

 

24 the value of $! is meaningful only immediately after a failure:

    if (open(FH, $filename)) {

        # Here $! is meaningless.

        ...

    } else {

        # ONLY here is $! meaningful.

        ...

        # Already here $! might be meaningless.

    }

    # Since here we might have either success or failure,

    # here $! is meaningless.

 

25

sub exec {

    local($ok, @cmd) = @_;

    foreach $word (@cmd) {

      $word =~ s#{}#$name#g;

    }

    if ($ok) {

      local($old) = select(STDOUT);

      $| = 1;

      print "@cmd";

      select($old);

      return 0 unless <STDIN> =~ /^y/;

    }

    chdir $cwd;         # sigh

    system @cmd;

    chdir $dir;

    return !$?;

}

 

26 lstat/stat

If stat is passed the special filehandle consisting of an underline, no stat is done, but the current contents of the stat structure from the last stat, lstat, or filetest are returned. Example:

    if (-x $file && (($d) = stat(_)) && $d < 0) {

        print "$file is executable NFS file/n";

    }

(This works on machines only for which the device number is negative under NFS.)

Because the mode contains both the file type and its permissions, you should mask off the file type portion and (s)printf using a "%o" if you want to see the real permissions.

    $mode = (stat($filename))[2];

    printf "Permissions are %04o/n", $mode & 07777;

 

27 打开管道

 用程序的形式也可以象命令行一样打开和使用管道(ex:ls > tempfile)。如语句open (MYPIPE, "| cat >hello"); 打开一个管道,发送到MYPIPE的输出成为命令"cat >hello"的输入。由于cat命令将显示输入文件的内容,故该语句等价于open(MYPIPE, ">hello"); 用管道发送邮件如下:

    open (MESSAGE, "| mail dave");

    print MESSAGE ("Hi, Dave! Your Perl program sent this!/n");

    close (MESSAGE);

 

28 <>操作符

<>操作符实际上是对数组@ARGV的隐含的引用,其工作原理为:
1、当PERL解释器第一次看到<>时,打开以$ARGV[0]为文件名的文件;
2、执行动作shift(@ARGV); 即把数组@ARGV的元素向前移动一个,其元素数量即减少了一个。
3<>操作符读取在第一步打开的文件中的所有行。
4、读完后,解释器回到第一步重复。
  例:
    @ARGV = ("myfile1", "myfile2"); #实际上由命令行参数赋值
    while ($line = <>) {
    print ($line);
    }
  将把文件myfile1myfile2的内容打印出来。

 

29  Singleton patten in Perl

package PSingleton;
 
  my $oneTrueSelf;
 
  sub new {
    if($oneTrueSelf) {
      return $oneTrueSelf;
    } else {
      my $type = shift;
      my $this = {
        presidents => ['George Washington', 'Thomas Jefferson',
                       'Theodore Roosevelt', 'Abraham Lincoln']
      };
      $oneTrueSelf = bless $this, $type;
    }
  }


 

 

参考资料:

网页の程序--Perl实例分析教程

 

Perl Reference

Documentation

Resource Topics

Programming
Core Documentation

perlfaq - perl常见问题集

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值