perl语言入门学习笔记
37305阅读 0评论 2012-10-12 飞鸿无痕
分类:LINUX
好久没写perl脚本了,基本忘得差不多了,呵呵,重新看一下perl语言入门吧。 perl内部并不存在整数,在perl内部总是按照双精度浮点数的要求来保存数字并进行运算的。 如果要使perl支持unicode字符,需要添加 use utf8; \l 将下一个字母转换为小写 \L 将它后面的所有字母都换为小写,直到\E为止 \u 将下一个字母转换为大写 \U 将它后面的所有字母都换为大写,直到\E为止 \Q 相当于把它到\E之间的非单词字符加上反斜杠 \E 结束\L、\U、\Q开始的作用范围 per的告警信息: use warnings; 或者使用 perl -w运行脚本 或者加上 #!/usr/bin/perl -w 如果看不懂告警,就是用 use diagnostics; 打印更详细的信息 $#aaa表示aaa数组的最后一个元素的索引值 关于perl中布尔值的判断 1、如果是数字,0为假;所有其他的为真 2、如果是字符串,空字符串为假,所有其他的字符串为真 3、如果既不是数字也不是字符串,那就先换成数字或者字符串再进行判断。 使用defined函数来判断变量是否定义 数组定义: my @p1=('aaa','bbb','ccc'); my @p2=(1..100); my @p3=qw(aaa bbb ccc); my @p4=qw! aaa bbb ccc !; $end=$#p1; $number=$#p1+1; $last=$p1[$#p1]; $last=$p1[-1]; pop取出数组中的最后的一个元素并将其作为返回值返回。 $last=pop(@p1); push添加元素到数组的最后 push(@p1,'jaj'); push @p1,'aaaa'; push @p1,@p2; shift取出数字第一个元素并将其作为返回值返回 $first=shift(@p1); unshift添加元素到数组的最左边 unshift(@p1,'jaj'); unshift @p1,@p2; splice可以实现从中间操作数组; foreach 来循环遍历数组中的值 reverse反转数组 sort 对数组进行排序 sort(@p1) 正向排序 reverse sort(@p1) 逆向排序 chomp(@p1); chomp(@line =); 可以使用state操作符来声明持久性私有变量 state $sum=0; state @numbers; 打印数组: print @array print "@array" @ARGV是存放所有参数的数组 <>砖石操作符,把输入参数当作文件处理 文件操作符(文件句柄) open CONFIG, 'test'; open CONFIG, 'open CONFIG, '>test'; open CONFIG, '>>test'; 关闭文件句柄: close CONFIG; 读取或者写入的时候指定文件的字符编码 open CONFIG, '<:encoding(UTF-8)', 'test'; open CONFIG, '>>:encoding(UTF-8)', 'test'; 打印perl能处理的字符编码清单 perl -MEncode -le "print for Encode->encodings(':all')" 判断文件句柄是否成功的代码: my $success=open CONFIG, '>>', test'; if( !$success ){ print "create file faild"; } if( ! open CONFIG, '>>', 'test' ){ die "Can't create config file: $!"; } if( @ARGV<2 ){ die "Not enough arguments\n"; } 自动检查致命错误 use autodie; 可以将文件句柄设置成变量,这样文件句柄可以作为子程序的参数传递,或者放在数组和hash中排序,或者严格控制其作用域。 打印往文件句柄中写入数据的时候不需要加入逗号! hash 申明hash my %test=('foo'=>35,'bar'=>39,'carl'=>34,'zhang'=>89); my %test=('foo',35,'bar',39,'carl',34,'zhang',89); 访问哈希元素 $hash{$key}; 哈希元素赋值 $hash{'test'}='carlzhang'; 访问整个hash my @any_array=%array; print "@any_array\n"; hash转换 my %test_hash=reverse %hash; hash函数 keys函数能返回hash的所有键列表 values函数能返回hash所有的值列表 my %test=('foo'=>35,'bar'=>39,'carl'=>34,'zhang'=>89); my @test_key=keys%test; my @test_value=values%test; print "test_key is: @test_key\n"; print "test_value is: @test_value\n"; 使用each函数遍历hash my %test=('foo'=>35,'bar'=>39,'carl'=>34,'zhang'=>89); while( my($test_key,$test_value)=each %test){ print "$test_key=>$test_value\n"; } my %test=('foo'=>35,'bar'=>39,'carl'=>34,'zhang'=>89); foreach my $test_key (sort keys %test){ my $test_value=$test{$test_key}; print "$test_key=>$test_value\n"; } 判断键值是否存在: if ( exists $test{'foo'}){ print "key fool is in test hash\n"; } 删除hash中的某个元素 delete $test{'foo'}; %ENV环境变量 my @test=%ENV; foreach $test_key (keys %ENV){ print "$test_key=>$ENV{$test_key}\n"; } 模式匹配: m/string/; m%string%; /string/; 使用/i忽略带小写 /string/i 用/s匹配任意字符 /test.*aaa/s 会匹配test和aaa之间的所有内容,包括换行符 用/x加入空白符,有了/x,perl会忽略空格和正则表达式中的perl风格的注释。 \A表示字符串开头 \z表示要匹配的字符串绝对末尾 \b匹配单词边界 \B不匹配单词边界 捕获 使用?:来指定不捕获小括号内的东东 使用?来命名捕获的内容,使用$+{LABEL}来提取捕获的内容 贪婪匹配 *? +? {1,}? {4,20}? ?? $^I 读取文件后对文件进行备份 perl模块 perldoc CGI 查看模块的用法 cpan -a 列出安装的模块 模块的安装: perl Makefile.PL make make install 可以在perl Makefile.PL后面通过INSTALL_BASE指定安装的路径 File::Basename和File::Spec的使用 use File::Basename; use File::Spec; my $name="/usr/local/bin/perl"; my $filename=basename $name; my $dirname=dirname $name; my $new_name=File::Spec->catfile($dirname,$filename); print "filename is $filename\n"; print "dirname is $dirname\n"; print "newname is $new_name\n"; 文件操作 文件测试操作符 -r 文件或者目录对当前用户或组来说是可读的 -w 文件或者目录对当前用户或组来说是可写的 -x 文件或者目录对当前用户或组来说是可执行的 -o 文件或目录由当前用户拥有 -R 文件或者目录对实际的用户或者组是可读的 -W 文件或者目录对实际的用户或者组是可写的 -X 文件或者目录对实际的用户或者组是可执行的 -O 文件或者目录由实际的用户拥有 -e 文件或者目录是存在的 -z 文件存在且没有内容(对目录来说永远为假) -s 文件或者目录存在而且有内容(返回值是以字节为单位的文件大小) -f 是普通文件 -d 是目录 -l 是符号链接 -S 是socket类型的文件 -p 是命名管道,也就是先入先出(fifo)队列 -b 是块设备文件(比如某个可挂载的磁盘) -c 是字符设备文件(比如某个I/O设备) -u 文件或者目录设置了setuid位 -g 文件或者目录设置了setgid位 -k 文件或者目录设置了sticky位 -t 文件句柄是TTY设备 -T 看起来像文本文件 -B 看起来像二进制文件 -M 最后一次被修改后至今的天数 -A 最后一次被访问后至今的天数 -C 最后一次文件节点编号(inode)被变更后至今的天数 测试统一文件的多项属性 if (-r $file and -w $file){ ..... } 可以改写成如下语句,以提高性能 if (-r $file and -w _){ ..... } _符号表示虚拟文件句柄,它会告诉perl用上次查询过的文件来做当前测试。 stat和lstat函数 stat函数返回一个有13个元素组成的列表。 dev 0 文件所在的设备编号 ino 1 文件的inode标号 mode 2 文件模式(权限、类型) nlink 3 文件或者目录的连接数 uid 4 文件的用户ID gid 5 文件的组ID rdev 6 设备识别码(只用于特殊文件) size 7 文件总的自己数 atime 8 文件最后访问时间 mtime 9 文件最后更改时间 ctime 10 inode更改的时间 blksize 11 文件系统I/O首选块的大小 blocks 12 实际分配的文件块数 localtime函数 ($sec,$min,$hour,$mday,$mon,$year_off,$wday,$yday,$isdat) = localtime; $sec 秒,0 ~ 59 $min 分,0 ~ 59 $hour 时,0 ~ 23 $mday 月份中的日期, 1 ~ 2 8、2 9、3 0或3 1 $mon 年份中的月份, 0 ~ 11(这里请特别要小心) $year_off 1900年以来的年份。将1900加上这个数字,得出正确的4位数年份 $wday 星期几,0 ~ 6 $yday 一年中的第几天,0 ~ 364或365 $isdst 如果夏令时有效,则为真 perl目录操作 chdir改变工作目录 chdir '/etc' or die "can't chdir to /etc: $!\n"; 在程序内部使用通配符匹配文件 my @files=glob '.* *'; #匹配多个模式需要用空格隔开,也可以采用my @files=<*>;的方式 print "@files\n"; opendir 打开目录 readdir 读取目录下的文件名 closedir 关闭打卡的目录句柄 测试代码: use File::Spec::Functions; my $dir='/etc'; opendir DIR,$dir or die "can't open /etc directory: $!\n"; foreach my $file (readdir DIR){ if ($file=~/^\./){ next; } $file=catfile($dir,$file); print "we found $file in /etc directory\n"; } closedir DIR; unlink删除文件,返回成功删除文件的数目,unlink不能用来删除目录 rename重命名文件 测试代码: for my $file (glob '*.old'){ my $new_file=$file; $new_file=~s/old/new/; if (-z $new_file){ print "$new_file is exists ,please check it out\n"; }else{ rename $file,$new_file or warn "rename $file faild,please check it out\n"; print "rename $file success ,don't worry\n"; } } 创建和删除目录 mkdir 创建目录 my $dir='aaa'; my $permissions="0755"; mkdir 'aaa',oct($permissions) or die "can't create directory aaa: $!\n"; rmdir删除目录,每次只能删除一个目录,而且删除时目录必须为空,不然会导致失败! chmod修改文件或者目录权限 chmod 0755,'test'; chown修改文件或者目录的属主或者属组,返回受影响的文件数量 测试代码: my $user=52; my $group=52; chown $user,$group,'bbb'; defined(my $user1=getpwnam 'puppet') or die "bad user: $!\n"; defined(my $group1=getpwnam 'puppet') or die 'bad group: $!\n'; chown $user1,$group1,'bbb.new'; utime修改文件的时间戳(最近的更改和访问时间) 测试代码: my $now=time; my $ago=$now-24*60*60; utime $now,$ago,'bbb'; 字符串和排序 用index查找子字符串 my $string='hah aaa bbbcc aa ddd'; my $part=index($string,'aa'); print "$part\n"; 排序 按照数字排序<=>; 按照字符排序cmp; my @some_numbers=qw{1 10 23 100 34 45}; my @some_chars=qw{aa cc bb dd dc bc}; sub by_number{ $a<=>$b; } sub by_char{ $a cmp $b; } my @test=sort by_number @some_numbers; my @test2=sort by_char @some_chars; print "@test\n"; print "@test2\n"; sub sort_test{ substr($test1{$a},2,6) <=> substr($test1{$b},2,6) or substr($test1{$a},0,1) cmp substr($test1{$b},0,1) } 执行外部命令 IPC::System::Simple system systemx capture capturex 错误扑捉: eval my $aaa1=$ARGV[0]; my $aaa2=$ARGV[1]; my $test=eval{$aaa1/$aaa2} || 'aaa'; print "I couldn't divide by \$aaa2: $@" if $@; print "$test"; 有4中类型的错误eval捕捉不到: 1、代码语法错误 2、perl解析器本省的崩溃错误 3、告警类错误 4、每次调用exit的时候