Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3045888
  • 博文数量: 535
  • 博客积分: 15788
  • 博客等级: 上将
  • 技术积分: 6507
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-07 09:11
文章分类

全部博文(535)

文章存档

2016年(1)

2015年(1)

2014年(10)

2013年(26)

2012年(43)

2011年(86)

2010年(76)

2009年(136)

2008年(97)

2007年(59)

分类: Python/Ruby

2009-08-27 10:24:17

20091013:
为@INC添加路径:we can wrap it in a BEGIN block. Perl executes the code in the BEGIN block during the compile phase before the require executes at runtime. Otherwise, Perl executes statements in the order that it finds them, and we have to ensure that our unshift shows up before our require.

BEGIN {
  unshift @INC, '/home/skipper/perl-lib';
}


This is such a common operation, though, that Perl has a pragma for it. The pragma makes everything happen before runtime, so we'll get what we expect. It puts the directories we specify at the beginning of @INC, just like we did before.

use lib qw(/home/skipper/perl-lib)


20091012:
1、使用IO::tee将输出同时写到两个不同的通道中:
IO::Tee multiplexes output. In this example, the castaways' log message goes to both the logfile and the scalar variable.

use IO::Tee;

$tee_fh = IO::Tee->new( $log_fh, $scalar_fh ); print $tee_fh "The radio works in the middle of the ocean!\n";


That's not all, though. If the first argument to IO::Tee is an input filehandle (the succeeding arguments must be output filehandles), we can use the same teed filehandle to read from input and write to the output. The source and destination channels are different, but we get to treat them as a single filehandle.

use IO::Tee;

$tee_fh = IO::Tee->new( $read_fh, $log_fh, $scalar_fh );

# reads from $read_fh
my $message = <$tee_fh>;

# prints to $log_fh and $scalar_fh
print $tee_fh $message;


$read_fh,第一个参数,是做为INPUT的,不一定是一个文件句柄,It might also be connected to a socket, a scalar variable, an external command's output, or anything else we can dream up.



20090924:
1、关于解引用时的{}
If the value inside the curly braces is a simple scalar variable, we can drop the braces。
当大括号里上一个简单的标量变量时,我们可以去掉大括号如:

& { $ref_to_greeter } ( 'Gilligan' )

当里面不是一个简单的标量变量时,则不可以,如:

& { $ref_to_array[1] } ( 'Gilligan' )

@{ $ref_to_ahash{greter} }

20090922
1、关于readdir的sort

opendir (my $dir,'/EBS/raid_disk/witz_log/log_bak') or die $!;

@files = 
    map{(split/ /,$_,2)[1]}
    sort
    map{sprintf"%8x %s",~(stat)[9],$_}
    grep{/\.log$/i}
    readdir $dir;

foreach $file(@files){

        next if $file =~ /^\.\.?$/;

#do something;

}



20090918
1、
you can add use diagnostics; at the beginning of your program, and any error message will look itself up in the documentation and display the entire detailed message. Don't leave this in production code, however, unless you like burning a lot of CPU cycles every time your program starts, whether or not an error occurs.
2、固定打印字符的宽度:

语法:printf FORMAT, LIST
printf "%40s","$source";

左对齐:
printf "%-40s","$source"


20090917
1、因为代码块block和匿名hash都使用“{}”,编译器有时会搞混你的意思,你需要为编译器添加提示,在匿名hash的开始{前添加一个加号“+”,在block里代码开始前加一个分号“;”,如下:

{;

  my @crew = (
    
+{
      name => 'Gilligan',
      hat => 'White',
      position => 'First Mate',
    },

    
+{
      name => 'Skipper',
      hat => 'Black',
      position => 'Captain',
    },
   );

}


20090915
1、关于eval的两种用法:
(1):eval BLOCK,用于捕捉异常
(2):eval EXPR,It compiles and executes code from a string at runtime.
注:尽量避免使用这种eval的这种用法。be very careful with this form of eval. If you can find another way to do what you need, try that first.

#!/usr/bin/perl

foreach my $operator ( qw(+ - * /) ) {
        my $result = eval "2 $operator 2";

warn $@ if $@;
        print "2 $operator 2 is $result\n";
        }


2、打印当前目录文件中文件的绝对路径

#!/usr/bin/perl -w
use Cwd;
use File::Spec;
my $curdir=getcwd;
opendir (my $D,"$curdir") or die $!;
print map{" ".File::Spec->catfile($curdir,$_)."\n"} readdir $D


3、


20090910
1、创建持续的私有变量
创建一个私有变量,使每次子过程调用该变量时都能保持变量的值,同时对子过程外是不可见的。
解决:将函数包在一个block代码块里,然后在代码块的范围内定义变量而不是在函数里定义变量。

{
    my $variable;
    sub mysub {
        # ... accessing $variable
    }
}

如果变量需要初始化,先要初始化代码块,以保证变量在主程序运行前被赋值。:

INIT{
    my $variable=1;
    sub mysub {
        # ... accessing $variable
    }
}



2、从函数众多的返回值中选择需要的返回值。

Either assign to a list that has undef in some positions:

($a, undef, $c) = func( )

 take a slice of the return list, selecting only what you want:

($a, $c) = (func( ))[0,2]

如果你想将一个表达式放到list上下文中,并且丢弃所有的返回值(仅仅为了表达式或函数的副作用),你可以将它赋值给一个空的list。(这种写法以前见过,没明白,现在要记住了)(可以理解为将返回的所有的值都设置为undef)

( ) = some_function( )


you can call it in list context and make sure it returns some non-zero number of items (which you immediately discard) like this:
你可以在list上下文中来调用,这样可以确保返回一个非零的项(函数的返回值立刻被丢弃了)If you hadn't assigned to the empty list, the Boolean context of the if test would have called the function in scalar context.
如果你没有赋值给一个空的list,if将会在scalar上下文中来调用函数并测试函数返回值的布尔值

if (( ) = some_function( )) { .... }

一个测试:
没有赋值给一个空的list:
#perl -e 'sub a{$a=1;$b=2; return undef} if (a()){print "return ok\n";}'
因为函数的返回值为空,所以if的block中的语句不会执行。

赋值给一个空的list:
#perl -e 'sub a{$a=1;return undef} if (()=a()){print "return ok\n";}'      return ok

4、使子过程返回多个数组或哈希
解决:函数想要返回多个独立的数组或hash需要使用引用,调用者(caller)准备好接受数组或哈希的引用。

($array_ref, $hash_ref) = somefunc( );

sub somefunc {
    my @array;
    my %hash;

    # ...

    return ( \@array, \%hash ); #or

    return \( @array, %hash ); #same thing
}


5、使用eval拦截程序的异常,并通过$@查看发生的异常。

eval { func( ) };
if ($@) {
    warn "func raised an exception: $@";
}


或者:

eval { func( ) }; warn "func raised an exception: $@" if $@;


6、关于local
local用于在一个{}块中保存一个变量的值

my @nums = (.. 5);
sub first { 
    local $nums[3] = 3.14159;
    second( );
}
sub second {
    print "@nums\n";

second( );
0 1 2 3 4 5
first( );
0 1 2 3.14159 4 5



20090909
1、关于readdir:
In scalar context, readdir returns the next filename in the directory until it reaches the end of the directory, when it returns undef. In list context it returns the rest of the filenames in the directory or an empty list if there were no files left.
the filenames returned by readdir do not include the directory name.

The readdir function will return the special directories "." (the directory itself) and ".." (the parent of the directory). Most people skip those files with code like:

while ( defined ($file = readdir BIN) ) {
    next if $file =~ /^\.\.?$/; # skip . and ..
    # ...
}

2、Globbing, or Getting a List of Filenames Matching a Pattern

Perl provides globbing with the semantics of the Unix C shell through the glob keyword and <>:

@list = <*.c>;
@list = glob("*.c")

3.递归的处理一个目录中的文件

Use the standard File::Find module.

use File::Find;
sub process_file {
    # do whatever;
}
find(\&process_file, @DIRLIST)

File::Find provides a convenient way to process a directory recursively. It does the directory scans and recursion for you. All you do is pass find a code reference and a list of directories. For each file in those directories, recursively, find calls your function.
4、保存传递到子过程的参数的特殊数组 @_The special array @_ holds the values passed in as the function's arguments. Thus, the first argument to the function is in $_[0], the second in $_[1], and so on. The number of arguments is simply scalar(@_).@_中的scalar就是真实的的参数,而不是参数的拷贝,也就是说如果你在子程序中更改了@_中的元素,你就是更改了真实的元素的值。解决的办法类似于下面:

You can write functions that leave their arguments intact by copying the arguments to private variables like this:

@nums = (1.4, 3.5, 6.7);
@ints = int_all(@nums); # @nums unchanged
sub int_all {
    my @retlist = @_; # make safe copy for return
    for my $n (@retlist) { $n = int($n) } 
    return @retlist;
}


20090907:
1、一个对象只不过是一个引用,
所有对象都是引用,但不是所有引用都是对象。一个引用不会作为对象运转,除非引用它的东西有特殊标记告诉 Perl 它属于哪个包。把一个引用和一个包名字标记起来(因此也和包中的类标记起来了,因为一个类就是一个包)的动作被称作赐福(blessing),你可以把赐福(bless)看作把一个引用转换成一个对象,尽管更准确地说是它把该引用转换成一个对象引用。

bless 函数接收一个或者两个参数。第一个参数是一个引用,而第二个是要把引用赐福(bless)成的包。如果忽略第二个参数,则使用当前包。

$obj = { }; # 把引用放到一个匿名散列 bless($obj); # Bless 散列到当前包 bless($obj, "Critter"); # Bless 散列到类 Critter。这里我们使用了一个指向匿名散列的引用,也是人们通常拿来做他们的对象的数据结构的东西。毕竟,散列极为灵活。不过请允许我们提醒你的是,你可以赐福(bless)一个引用为任何你在 Perl 里可以用作引用的东西,包括标量,数组,子过程和类型团。
这就是如何制作对象。只需要使用某事的引用,通过把他赐福(bless)到一个包里给他赋一个类,仅此而已。

2、你可以把一个标量,数组,散列或者文件句柄(通过它的类型团)系到任意一个类(就是包)上,这个类提供合适的命名方法以截获和模拟对这些对象的正常访问。

tied 函数在该普通变量上检索该对象:

tie VARIABLE, CLASSNAME, LIST; # 把VARIABLE 绑定到 CLASSNAME $object = tied VARIABLE;

上面两行等效于:

$object = tie VARIABLE, CLASSNAME, LIST;
你几乎完全可以把 tie 看作一种有趣的 bless 类型,只不过它是给一个光秃秃的变量赐福,而不是给一个对象引用赐福。

20090904:
1、The special variable $. holds the number of lines read since a filehandle was last explicitly closed:

while <FILE>;
$count = $.

This reads in all records in the file, then discards them.

或者:

perl -'open (my $file,"<","./1.pl") or die "$1";while(<$file>){};$count=$.;print $count;'

 $.   为最后访问的文件句柄对应的当前行号(Perl中行的概念也许和你不一 样,要看 $/ 的值是什么。)。关闭文件句柄时会复位 $.,但在没有 close()就重新打开一个已打开的文件句柄 时不会这样。
2、模拟tail -f的功能

You want to read from a continually growing file, but the read fails when you reach the current end-of-file.

Read until end-of-file. Sleep, clear the EOF flag, and read some more. Repeat until interrupted. To clear the EOF flag, either use seek:

到达文件结尾时,清除EOF,或者使用seek,下面的例子使用seek。

The seek code given in the Solution tries to move zero bytes from the current position, which nearly always works. It doesn't change the current position, but it should clear the end-of-file condition on the handle so that the next <$log> operation picks up new data.

关于清除EOF,use the IO::Handle module's clearerr method

open (my $log,"<","/usr/local/nginx/logs/access.log") or die "$!";

seek($log,0,2); #到达文件的结尾

for(;;){

while(<$log>){print };

sleep 1;

seek($log,0,1); #从当前位置读起

}

如果这个方法不生效,查看perldoc中的写法:
command line:

perl -'open (my $log,"<","/usr/local/nginx/logs/access.log") or die "$!";seek($log,0,2);for(;;){while(<$log>){print };sleep 1;seek($log,0,1);}'



20090903:
1、关于输入的分隔符:
由变量“$/"来决定,默认为"\n",
Undefine $/ to read the rest of the file as one scalar:

undef $/;
$whole_file = <FILE>; # "slurp" mode


2、seek函数:seek FILEHANDLE,POSITION,WHENCESets FILEHANDLE's position,设置文件句柄的位置。

seek(LOGFILE, 0, 2) or die "Couldn't seek to the end: $!\n";

3个参数:
filehandle:文件句柄position:移动的字节数(正数向前,负数向后)whence:为0时,从文件头开始移动,为1时,相对于当前位置(将要读的下一行)移动,and 2, an offset from end-of-file(对于2,设置position基本上是无意义的,因为已经到达文件的EOF了).The values for WHENCE are 0 to set the new position in bytes to POSITION, 1 to set it to the current position plus POSITION, and 2 to set it to EOF plus POSITION (typically negative).A WHENCE of 1 (SEEK_CUR ) is useful for not moving the file position:
3、readline or , print, read, seek, and tell 都是buffered I/O.Perl also provides an alternate set of I/O operations guaranteed to be unbuffered no matter what I/O layer is associated with the handle. These are sysread, syswrite, and sysseek
20090902:
1、perl 参数中的-n -p -e
-n :The -n option adds the while (<>) loop around your program text. It's normally used for filters like grep or programs that summarize the data they read.
相当于为程序加了一个while循环,可以处理多个文件或文件的多行。

下面的例子是没有加-n的例子,处理一个文件时,需要使用while(<>)循环(注意后面红色字体的部分),注意,里面的print。在后面的例子中可以省略掉这个print。

#!/usr/bin/perl
  # findlogin1 - print all lines containing the string "login"
  while (<>) {# loop over files on command line 
      print if /login/;
  }

下面的例子,使用了-n 参数,省略了while(<>)循环。

#!/usr/bin/perl -n
  # findlogin2 - print all lines containing the string "login"
  print if /login/


-p:功能和-n相同,可以省略掉while(<>),同时,-p还省略掉了上面例子中的print。

#!/usr/bin/perl -p
  # findlogin2 - print all lines containing the string "login"
  if /login/


-i:备份修改前的文件,(想想sed的-i,功能是一样的),下面的例子,在命令行中运行,替换3个文件中的字符a,并备份替换前的文件。

perl -i.bak -pe 's/a/b/g' a.txt b.txt c.txt

The -i switch takes care of making a backup (say -i instead of -i.orig to discard the original file contents instead of backing them up), and -p makes Perl loop over filenames given on the command line (or STDIN if no files were given).

上面的例子如果改成使用-n的话为:

perl -i.bak -n's/a/b/g;print;' a.txt b.txt c.txt


-e 选项涵义是“执行下面的代码”

perl -we 'my @log_files=glob "*.log";foreach (@log_files){print "$_\n";}'


perl -w' foreach (<>){print if /customcookies/}' access_20100309-19

perl -w' while (<>){print if /customcookies/}' access_20100309-19


2、关于打印输出到文件句柄的缓存问题。
When printing to a filehandle, output doesn't appear immediately.

Disable buffering by setting the per-filehandle variable $| to a true value, customarily 1:

$old_fh = select(OUTPUT_HANDLE);
$| = 1;
select($old_fh)

select:选择默认的STDOUT

Or, if you don't mind the expense of loading an IO module, disable buffering by invoking the autoflush method:

use IO::Handle;
OUTPUT_HANDLE->autoflush(1)

This works with indirect filehandles as well:

use IO::Handle;
$fh->autoflush(1)

注:小的脚本使用$|就可以了,大的应用使用IO::Handle

20090901:
创建临时文件:
Use the tempfile function from the File::Temp module:

use File::Temp qw/ tempdir /;
$fh = tempfile( ); # just the handle

In scalar context, it returns a filehandle to that temporary file; in list context, it returns the handle and pathname of the temporary file:

use File::Temp qw(tempfile);

# just the handle
$fh = tempfile( );

# handle and filename
($fh, $filename) = tempfile( )


specify UNLINK => 1, the temporary file will be deleted automatically when your program finally exits or the file is closed.

($fh, $filename) = tempfile(UNLINK => 1)

更详细的用法查看文档。


20090831:
更改print的默认stdout。
STDOUT is the default filehandle used by the print, printf, and write functions if no filehandle argument is passed. Change this default with select, which takes the new default output filehandle and returns the previous one. The new output filehandle must have already been opened before calling select:

$old_fh = select(LOGFILE); # switch to LOGFILE for output
print "Countdown initiated ...\n";
select($old_fh); # return to original output
print "You have 30 seconds to reach minimum safety distance.\n"

如果仅仅是更改一次的话,直接在print后面加文件句柄(在这之前要先打开文件句柄):

open (my $log,">","/tmp/run.log" or die "fail: $!";
print $log "open file ok\n"



20090827:
1、关于找到第N次匹配
一般使用/g修饰符和while循环

# simple way with while loop $count = 0; while ($string =~ /PAT/g) { $count++; # or whatever you'd like to do here } # same thing with trailing while $count = 0; $count++ while $string =~ /PAT/g; # or with for loop for ($count = 0; $string =~ /PAT/g; $count++) { } # Similar, but this time count overlapping matches $count++ while $string =~ /(?=PAT)/g;


另一种方法,保存所有的匹配,然后去找自己需要的。

$pond = 'One fish two fish red fish blue fish';

# using a temporary
@colors = ($pond =~ /(\w+)\s+fish\b/gi); # get all matches
$color = $colors[2]; # then the one we want

or without a temporary array
$color = ( $pond =~ /(\w+)\s+fish\b/gi )[2]; # just grab element 3

print "The third fish in the pond is $color.\n";
The third fish in the pond is red.


2.两种打开文件的方式。推荐使用第2种,automatically allocates an anonymous typeglob and stores its reference into the previously undefined variable
"Perl autovivifies filehandles passed to open as undefined scalars."

open(INPUT, "<", "/acme/widgets/data")
    or die "Couldn't open /acme/widgets/data for reading: $!\n";
while (<INPUT>) {
    print if /blue/;
}
close(INPUT)



my $input; # new lexical starts out undef
open($input, "<", "/acme/widgets/data")
    or die "Couldn't open /acme/widgets/data for reading: $!\n";
while (<$input>) {
    print if /blue/;
}
close($input); # also occurs when $input GC


3.使用mkpath创建目录

use File::Path;
mkpath (['/home/jason/perl/quux'], 0, 0711)

其中,中间的那个参数0表示不打印创建文件夹的文件名。which if TRUE will cause "mkpath" to print the name of each directory as it is created (defaults to FALSE)

4、删除文件,删除空目录,删除非空目录
删除文件:

unlink '/home/jason/perl/2018035‘


删除空目录:

rmdir '/home/jason/perl/quux'


删除非空目录:使用File::Path

use File::Path;
rmtree '/home/jason/perl/test'


其中unlink和rmdir为perl的builtin function
rmtree为  File::Path中的function

20090826:
1.pattern match中的 ?=
?=是往前看,在下面的例子中,不光要匹配man,而且要继续往前看,前面是数字才是匹配上了。也就是说真正要匹配的内容不包括“?=”的内容,“?=”只是起一个辅助的作用。
一个例子:

# /usr/man/man3/foo.1 changes to /usr/man/cat3/foo.1
($catpage = $manpage) =~ s/man(?=\d)/cat/

详细查看:perldoc perlre
"(?=pattern)" A zero-width positive look-ahead assertion.  For example, "/\w+(?=\t)/" matches a word followed by a tab, without including the tab in $&.
$&为正则匹配的部分。
验证:

echo ttr3|perl -ne 'print $& if /\w+(?=\d)/'

输出为 ttr,即不包括后面的3.

对应的还有:
往前看(真)(Positive Look-ahead)  (?=pattern)
往后看(真)(Positive Look-behind) (?<=pattern)
往前看(否)(Negative Look-ahead)  (?!pattern) 例如:匹配man而且man后面不是3的
往后看(否)(Negative Look-behind) (?

另:

[[ 扩展模式 - 非捕捉群组 (Non-capturing groupings) ]]


语法:

(?:pattern)


之前提到括号有个特別的作用,就是会把配到的东西放进 $1, $2,...,

例如:


$time_string = '12:34:56';

$pattern = '(\d\d):(\d\d):(\d\d)';


if ($time_string =~ /$pattern/) {

($hour, $minute, $second) = ($1, $2, $3);

print "hour=$hour,minute=$minute,second=$second";

}


但如果您不想放的话,可以用 (?:pattern):


$time_string = '12:34:56';

$pattern = '(\d\d):(?:\d\d):(\d\d)';


if ($time_string =~ /$pattern/) {

($hour, $minute, $second) = ($1, $2, $3);

print "hour=$hour,minute=$minute,second=$second";

}


因为「分」那部份使用了(?:pattern) ,所以就不会放到本來的 $2,这就轮到「秒」的部份放到 $2了。


[[ 伸展模式 - 內嵌修饰词 (Embedded Modifiers) ]]

语法:

(?imsx-imsx:pattern)


之前提到可以用 i 修饰词來做不分大小写的配对,例如:


$st = '11AB22Ab33aB44ab';

$pattern = 'AB';


@matches = $st =~ /$pattern/ig;


这样整个 $pattern 都是不分大小写了,

如果想某部份分辨大小写,某部份不分辨,可以用內嵌的写法。


$st = '11AB22Ab33aB44ab';

$pattern = '(?i:A)(?-i:B)';


@matches = $st =~ /$pattern/g;


表示 A 不分大小写,B 就分辨大小写。

如果修饰词前面是減号,表示关闭该修饰词,

例如 (?s-i),表示启动 s 修饰词,关闭 i 修饰词。


其实內嵌修饰词的語法,是在非捕捉群组內加入修饰词而己。




2、do BLOCK
Not really a function. Returns the value of the last command in the sequence of commands indicated by BLOCK. When modified by the while or until loop modifier, executes the BLOCK once before testing the loop condition.


20090825:
统计出现的次数:
Any time you want to count how often different things appear, you should probably be using a hash. The foreach adds one to $count{$element} for every occurrence of $element.

%count = ( );
foreach $element (@ARRAY) {
    $count{$element}++;
}


测试:
  1. #!/usr/bin/perl -w
  2. @ARRAY=qw/9 1 2 3 4 5 6 1 3 4 2 5 1 6 1/;
  3. %count = ( );
  4. %uniq=();
  5. foreach $element (@ARRAY) {
  6. $count{$element}++;
  7. $uniq{$element}=1 unless exists $uniq{$element};
  8. }
  9. map {print "$_ $count{$_}\n"} keys %uniq


20090824:
1、splice:
 pop or shift multiple elements at a time
The splice function allows you to add elements, delete elements, or both, at any point in an array, not just at the ends.

# remove $N elements from front of @ARRAY (shift $N)
@FRONT = splice(@ARRAY, 0, $N);

# remove $N elements from the end of the array (pop $N)
@END = splice(@ARRAY, -$N)


2.sorting an array numberically

@sorted = sort { $a <=> $b } @unsorted;

$a,$b是localized的动态临时变量。
sort提供两种比较的操作符,”cmp“和”<=>",默认是cmp模式,即按字母顺序的比较,如11 cmp 6时,6排在11的后面
$a <=> $b 默认为升序,如果想要降序,使用$b <=> $a 

按字符串长度排列

@sorted = sort { length$<=> length$b } @unsorted



20090821:
1.几乎所有在perl中关于一个scalar是否存在于一个list而不存在于另一个list中的问题,都使用hash来解决。
如:找出存在于@A,而不存在于@B中的scalar。
<1>:以每一个@B中的elements为key,设置value为1的hash,(如%seen)
<2>:轮询每个存在于@A中的elements,使用hash的exists函数检查该elements是否为%seen的key,如果存在这样的key,则说明该elements存在于@B中,不做处理。如果不存在,则该elements不存在于@B中,将该elements push要一个新的数组中做为结果。

#!/usr/bin/perl -w
@A=qw/a b c d e h/;
@B=qw/j k o w s a h r h/;

my%seen;
my@a_only;
# build lookup table
foreach $item_b(@B){
        $seen{$item_b}=1;
};
# find only elements in @A and not in @B
foreach $item_a(@A){
        push(@a_only,$item_a) unless exists $seen{$item_a};
};
print "@a_only\n"


2.另一种初始化hash的方法:

A hash slice is easiest illustrated by this example:

$hash{"key1"} = 1; $hash{"key2"} = 2;

which is equivalent to:

@hash{"key1", "key2"} = (1,2);

The list in the curly braces holds the keys; the list on the right holds the values. We initialize %seen in the first solution by looping over each element in @B and setting the appropriate value of %seen to 1. 

foreach $item_b(@B){
        $seen{$item_b}=1;
};

we simply say:

@seen{@B} = ( ); 建立了一个hash,每个@B的elements对应的value为undef。如何赋值??@seen{@B}=(1) x @B;
3.所以,上面的方法更改为

my %seen; # lookup table
my @aonly; # answer

# build lookup table
@seen{@B} = ( );

foreach $item (@A) {
    push(@aonly, $item) unless exists $seen{$item};
}

4、同样的问题,但,是对于文件的操作。

open(OLD, $path1) || die "can't open $path1: $!";
@seen{ <OLD> } = ( );
open(NEW, $path2) || die "can't open $path2: $!";
while (<NEW>) {
    print if exists $seen{$_}; 
}



20090820:
1.计算两个时间的差别

#!/usr/bin/perl -w
use Date::Calc qw(Delta_DHMS);
(@later)=(2009,8,7,11,23,54);
(@early)=(2009,7,7,23,45,23);
@diff=Delta_DHMS(@early,@later);
print "$diff[0] days, $diff[1]:$diff[2]:$diff[3] after early\n"

更多关于时间的计算,查看 perldoc Date::Calc

2、关于localtime输出格式以及计算时间差别的测试。

#!/usr/bin/perl -w
use Time::localtime;
use Date::Calc qw(Delta_DHMS);

sub cur_time{
$tm=localtime; #Time::tm - internal object used by Time::gmtime and Time::localtime.detail:perldoc Time::tm
our($year,$month,$day,$hour,$min,$sec)=($tm->year+1900,$tm->mon+1,$tm->mday,$tm->hour,$tm->min,$tm->sec);
#our for globe var
($sec,$min,$hour,$day,$month,$year) = (
    sprintf("%02d", $sec),
    sprintf("%02d", $min),
    sprintf("%02d", $hour),
    sprintf("%02d", $day),
    sprintf("%02d", $month + 1),
    substr($year,2,2) #is 09,if you want 2009,change this line to $year
    #$year
);
my$times="$year$month$day-$hour:$min:$sec";
print "$times\n";
}

#test for diff of two times
cur_time;
(@early)=($year,$month,$day,$hour,$min,$sec);
sleep 4;
cur_time;
(@later)=($year,$month,$day,$hour,$min,$sec);

@diff=Delta_DHMS(@early,@later);
print  "use time : $diff[0] days,$diff[1] hours,$diff[2] minutes,$diff[3] seconds \n"



用于shell中的例子

#!/bin/bash

function perl_time(){

perl -we'

use Date::Calc qw(Today_and_Now);

@times_n= Today_and_Now();

        time2=`perl_time`

print "@times_n\n";'


function time_diff(){

#usage time_diff "$time1" "$time2" ,argv must with ""

perl -we'

        use Date::Calc qw(Delta_DHMS);

        @diff=Delta_DHMS(@ARGV);

        print "Use time : $diff[0] days,$diff[1] hours,$diff[2] minutes,$diff[3] seconds \n"' $1 $2

}


time1=`perl_time`
sleep 2
time2=`perl_time`
time_diff "$time1" "$time2"

注意,%C

# simple way with while loop
$count = 0;
while ($string =~ /PAT/g) {
    $count++; # or whatever you



晕死了,这篇文章中丢了好多的内容,也没备份,郁闷啊~~~~~~~~破电脑
具体丢了多少内容想不起来了,下面是想起的一部分内容。
1、使用open ipc

open(STATUS, "netstat -an 2>&1 |")
         || die "can't fork: $!";
    while (<STATUS>) {
    next if /^(tcp|udp)/;
    print;
    }
    close STATUS || die "bad netstat: $! $?"

详细查看:



很早以前:
1.将一个标量转变成数组
如:某个标量为:
$line="[tcp        0      0 172.18.3.131:57882          172.18.3.135:3306   ESTABLISHED ]";
@db_con=split(“ ”, $line);
print $db_con[4];

split /PATTERN/,EXPR
Perl中的一个非常有用的函数是split - 把字符串进行分割并把分割后的结果放入数组中  
如果分隔符是“|”的话,需要使用\来防止“|”转义,因为“|”在正则中试“或”
perl -e'@d=split(/\|/,"12345|6789");print "@d"'

2、


3、解引用:使用过程中只有一个最高级的原则:Perl 不会做任何隐含的引用或者解引用动作。
如果一个标量挂在了一个引用上,那么它总是表现出简单标量的行为。它不会突然就成为一个数组或者散列或是子过程,你必须明确地告诉它进行转变,方法就是对它解引用。所以
If you print the value of a reference (or pointer), you will see an address. If you want to go to that address and get the value stored there—that is, dereference the pointer—the pointer must be prefaced by two "funny" symbols. The first is the dollar sign, because the pointer itself is a scalar, and preceding that goes the funny symbol representing the type of data to which it points. When using more complex types, the arrow (infix) operator can be used.
如果你打印一个引用的值,你将获得一个地址,类似于ARRAY(0x815bc28)、SCALAR(0x94de630)、HASH(0x8ebec28)、CODE(0x8c46654)。如果你想到达这个地址,获取这个地址存放的实际值,在引用的前面加上“趣味字符”来解引用。

数组:     
    创建引用:my $reference_to_skipper = \@skipper;
    解引用:    普通数组            数组引用
         @ skipper          @{ $items } 演变:@$items(下面的也一样)

$skipper[3]        ${$reference_to_skipper}[3] 太难阅读,所以我们这样写 $reference_to_skipper->[3](不要和$reference_to_skipper[3]相混淆)

hash:
    创建引用:my $hash_ref = \%gilligan_info;
    解引用:普通hash                     hash引用
        my @keys = keys %gilligan_info;         my @keys = keys % $hash_ref ;
        my $name = $gilligan_info { 'name' };   my $name = $hash_ref { 'name'};
        ${$hash_ref}{red} 写的太笨重, 所以我们这样写  my $name =$hash_ref->{'name'};


sub:    创建引用:my $ref_to_greeter = \&skipper_greets;
    解引用:普通sub                         sub引用
        & skipper_greets ( 'Gilligan' )         $ref_to_greeter ( 'Gilligan')
                             $ref_to_greeter -> ('Gilligan' )



创建hash引用的两种方法:
方法1.
先创建hash

my %last_name = ( # a hash may be a lexical variable
      "fred" => "flintstone",
      "dino" => undef,
    )

创建hash的引用

$hash_ref=\%last_name

"\"的作用类似有C中的“&”,用于获取地址“address of"

方法2
创建一个匿名hash,并返回一个指向这个hash的引用(注意,是大括号)。 { ITEMS } 创建了一个新的、匿名的哈希,并返回那个哈希的一个'引用'。

$href = { APR =>; 4, AUG =>; 8 }



创建array引用:
方法1:

@array = (1, 2, 3);
$aref = \@array

方法2

$aref = [ 1, "foo", undef, 13 ];

方法3

@$aref=qw(a b c d);

print $aref;

其中$aref即为reference

In other words, saying $a = \$b makes $$a and $b the same piece of memory. If you say $$a = 3, then $b is set to 3, even though you only mentioned $a by name, not $b.





The $  means you are working with a single value, which can be a scalar variable or a single element accessed in an array or hash:
$scalar
$array[3]
$hash{'key'}

The @  means you are working with multiple values, so you’ll use it with arrays or hashes, since they are the only collection types Perl has:
@array
@array[0,2,6] # an array slice
@hash{ qw(key1 key2) } # a hash slice

The %  sign is a bit special. It means you’re treating something as a hash, and there is only one variable type and access method that can act as a hash, 
which is the whole hash itself:
%hash

Perl also has sigils for subroutines (&) and typeglobs (*), but they are used 
only for those types, so we won’t bother with them here.














阅读(2651) | 评论(0) | 转发(0) |
0

上一篇:perl中的map函数

下一篇:安装perl Net::SSH2

给主人留下些什么吧!~~