分类: Python/Ruby
2009-08-27 10:24:17
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)
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;
$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.
$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;
& { $ref_to_greeter } ( 'Gilligan' ) |
& { $ref_to_array[1] } ( 'Gilligan' ) @{ $ref_to_ahash{greter} } |
opendir (my $dir,'/EBS/raid_disk/witz_log/log_bak') or die $!; @files = foreach $file(@files){ next if $file =~ /^\.\.?$/; #do something; } |
语法:printf FORMAT, LIST |
{; my @crew = ( } |
#!/usr/bin/perl warn $@ if $@; |
#!/usr/bin/perl -w |
{ |
INIT{ |
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] |
( ) = some_function( ) |
if (( ) = some_function( )) { .... } |
($array_ref, $hash_ref) = somefunc( ); return \( @array, %hash ); #same thing |
eval { func( ) }; 或者: eval { func( ) }; warn "func raised an exception: $@" if $@; |
my @nums = (0 .. 5); |
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) ) { |
Perl provides globbing with the semantics of the Unix C shell through the glob keyword and <>:
@list = <*.c>; |
Use the standard File::Find module.
use File::Find; |
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); |
bless 函数接收一个或者两个参数。第一个参数是一个引用,而第二个是要把引用赐福(bless)成的包。如果忽略第二个参数,则使用当前包。
$obj = { }; # 把引用放到一个匿名散列 bless($obj); # Bless 散列到当前包 bless($obj, "Critter"); # Bless 散列到类 Critter。这里我们使用了一个指向匿名散列的引用,也是人们通常拿来做他们的对象的数据结构的东西。毕竟,散列极为灵活。不过请允许我们提醒你的是,你可以赐福(bless)一个引用为任何你在 Perl 里可以用作引用的东西,包括标量,数组,子过程和类型团。tied 函数在该普通变量上检索该对象:
tie VARIABLE, CLASSNAME, LIST; # 把VARIABLE 绑定到 CLASSNAME $object = tied VARIABLE;
上面两行等效于:
$object = tie VARIABLE, CLASSNAME, LIST;1 while <FILE>; |
This reads in all records in the file, then discards them.
或者:
perl -e 'open (my $file,"<","./1.pl") or die "$1";while(<$file>){};$count=$.;print $count;'
$. 为最后访问的文件句柄对应的当前行号(Perl中行的概念也许和你不一 样,要看 $/ 的值是什么。)。关闭文件句柄时会复位 $.,但在没有 close()就重新打开一个已打开的文件句柄 时不会这样。
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); #从当前位置读起 } |
perl -e '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);}' |
undef $/; |
seek(LOGFILE, 0, 2) or die "Couldn't seek to the end: $!\n"; |
#!/usr/bin/perl |
#!/usr/bin/perl -n |
#!/usr/bin/perl -p |
perl -i.bak -pe 's/a/b/g' a.txt b.txt c.txt |
perl -i.bak -ne 's/a/b/g;print;' a.txt b.txt c.txt |
perl -we 'my @log_files=glob "*.log";foreach (@log_files){print "$_\n";}' |
perl -we ' foreach (<>){print if /customcookies/}' access_20100309-19 perl -we ' while (<>){print if /customcookies/}' access_20100309-19 |
Disable buffering by setting the per-filehandle variable $| to a true value, customarily 1:
$old_fh = select(OUTPUT_HANDLE); |
Or, if you don't mind the expense of loading an IO module, disable buffering by invoking the autoflush method:
use IO::Handle; |
This works with indirect filehandles as well:
use IO::Handle; |
use File::Temp qw/ tempdir /; |
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)
$old_fh = select(LOGFILE); # switch to LOGFILE for output |
open (my $log,">","/tmp/run.log") or die "fail: $!"; |
# 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'; |
open(INPUT, "<", "/acme/widgets/data") |
my $input; # new lexical starts out undef |
use File::Path; |
unlink '/home/jason/perl/2018035‘ |
rmdir '/home/jason/perl/quux' |
use File::Path; |
# /usr/man/man3/foo.1 changes to /usr/man/cat3/foo.1 |
echo ttr3|perl -ne 'print $& if /\w+(?=\d)/' |
另: [[ 扩展模式 - 非捕捉群组 (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 修饰词。 其实內嵌修饰词的語法,是在非捕捉群组內加入修饰词而己。 |
%count = ( ); |
# remove $N elements from front of @ARRAY (shift $N) |
@sorted = sort { $a <=> $b } @unsorted; |
@sorted = sort { length$a <=> length$b } @unsorted |
#!/usr/bin/perl -w |
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;my %seen; # lookup table |
open(OLD, $path1) || die "can't open $path1: $!"; |
#!/usr/bin/perl -w |
#!/usr/bin/perl -w |
#!/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" |
# simple way with while loop |
open(STATUS, "netstat -an 2>&1 |") |
数组: $skipper[3] ${$reference_to_skipper}[3] 太难阅读,所以我们这样写 $reference_to_skipper->[3](不要和$reference_to_skipper[3]相混淆) hash:
|
my %last_name = ( # a hash may be a lexical variable |
$hash_ref=\%last_name |
$href = { APR =>; 4, AUG =>; 8 } |
@array = (1, 2, 3); |
$aref = [ 1, "foo", undef, 13 ]; |
@$aref=qw(a b c d); print $aref; |