Perl笔记

Perl相关的一些笔记。

module相关

查找已安装的perl module

1
find `perl -e '{print "@INC";}'` -name '*.pm'

Perl模块安装到非默认路径及其使用

1
2
3
4
perl Makefile.PL PREFIX=/your/path
make
make test
make install

Perl非默认路径模块的引用

1
use lib '/lib/path';

或者将其加入环境变量PERLLIB

1
export PERLLIB=$PERLLIB:/lib/path

读写文件

直接读取压缩文件

.gz格式文件

1
open(FIN,"gzip -dc $infilename|") or die ("can not open $infilename\n");

.tgz(.tar.gz)格式文件

1
open(FIN,"tar -xf $infilename -o|") or die ("can not open $infilename\n");

7zip格式文件

1
open(FIN,"7za e -so $infilename|") or die ("can not open $infilename\n");

改变读取文件的分割符

默认为换行,可更改为其他,例如改为”>”

1
local $/ = ">";

输出控制

控制输出小数的位数,例如输出两位小数。

1
2
$p=1/456;
printf "%.2f",$p;

如果不想输出,只想转化以下,可以用sprintf函数。

1
$a=sprintf("%.2f",$p);

输出两个反斜杠

1
$slash='\\' x 2

打印整块文本

1
2
3
print << 'EOT' 
blah blah
EOT

随机数

函数randsrand,函数rand()会返回一个处于0和你所指定的数值(缺省为1)之间的分数。如果你在第一次调用rand()之前没有调用srand(),那么系统会为你自动调用srand()。

1
2
3
srand; #要先宣告srand函数,才能产生随机数的效果
$int=rand(10); #$int的值会大于0而且小于10如果希望产生的乱数是整数的话,就要再加上int #这个函数
$int=int(rand(10)); #$int的值是一个整数,且值在0和9之间

哈希相关

二维哈希

赋值

1
2
my %hash;
$hash{$key}{$key2}=2;

遍历

普通遍历

1
2
3
foreach my $key (keys %hash){
foreach my $key2 (keys %{$hash{$key}})
}

按key值大小遍历

1
2
3
4
5
6
foreach my $key(sort{$b<=>$a}(keys %hash))
{
foreach my $key2 (sort{$b<=>$a}(keys %{$hash{$key}})){
print “$key\t$key2\t$hash{$key}{$key2}\n";
}
}

哈希的值为数组

赋值

1
2
my %t1;
push @{$t1{$key}}, $a;

调用

1
2
3
foreach my $key (keys %t1) {
print @{$t1{$key}};;
}

进程相关

多进程实现

fork函数,调用fork函数的意义是复制一个和父进程完全一样的子进程。如何在程序里区分不同进程?需要用fork的返回值控制,父进程中fork调用后产生的返回值为子进程的进程号,而在子进程中范围值是0,因此可以用一个简单的if esle结构控制。

1
2
3
4
5
6
7
my $pid=fork(); #产生一个子进程
if($pid!=0){
执行父进程命令;
}
else{
执行子进程命令;
}

不同进程间的通信

pipe函数,参数传递可以用pipe函数,其用法pipe(infile, outfile),infile是用于读的文件句柄,outfile是用于写的文件句柄。

以下例子显示变量$a如何从父进程赋值传递给子进程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$|=1;
my $a;
pipe(INPUT,OUTPUT);
if($pid=fork()){print "wait..\n";
close (INPUT);
$a=10;
print "parent a is $a\n";
print OUTPUT $a;}
elsif(defined $pid){
#sleep(3);
print "kid doing\n";
close(OUTPUT);
$a=<INPUT>;
print "kid a is $a\n";
exit(0);
}

perl单命令行操作

参数解释

-e执行code
-p循环每行并输出
-n循环每行但不输出
-i执行替换
-a分割行 -F 指定分割符
-M使用模块
-h单命令行的帮助

内建变量

$_本行
$.行号

文件内替换字符串

1
2
perl -pi -e 's/you/me/g' file #文件内的you全部替换为me
perl -pi -e 's/you/me/g if /we/' file #文件内的有we的行的you才全部替换为me

输出重复的行

1
perl -ne 'print if $a{$_}++' file #输出重复的行,直接定义一个hash并纪录每行

输出行号

-ne 'print "$. $_"'
1
2
#或者  
perl -pe '$_ = "$. $_"'

用冒号分割行

1
perl -aln -F: -e 'print "$F[2]\t$F[0]"' /etc/passwd

安装模块

1
perl -MCPAN -e'install List::Util'

使用模块

打出每行内元素之和

1
perl -MList::Util=sum -alne 'print sum @F' #-a参数用来split每行 -l输出结果时添加换行符 @F是a分割后的数组

产生8位随机密码

1
perl -le 'print map { (a..z)[rand 26] } 1..8'
测试