perl文件句柄的理解(tell、seek)以及文本多行匹配的一种算法

来源:互联网 发布:nginx 图片服务器配置 编辑:程序博客网 时间:2024/05/19 08:05

  • perl文件句柄的理解
  • 文本多行匹配的一种算法
  • seek - reposition file pointer for random-access IO
  • tell - get current seekpointer on a filehandle
  • seek和tell一般是配套使用
    • 例子连续执行两次whilefileh的结果
    • 增加tell和seek的使用
  • 参考文档

下述理解,完全是个人体会。自觉有点道理。

perl文件句柄的理解

句柄,又叫指针;下文,我也称之为头地址,因为更形象一些。
文件句柄,就是指向文件内容的内存空间范围的头地址;文件句柄读取一次,起始地址+1,即读取下一行(perl里默认是一行一行读取文本的。可以设置间隔符$/,使之不是\n)。这一段,是个人体会,不知正确否。以硬件角度,类似FIFO及FIFO读指针(ps:先入先出,而非堆栈,FILO,先入后出)

qilei@AFAAW-704030720:~$ cat test.txta11111a22222a33333a44444a55555a66666a77777a88888a99999a00000b11111b22222b33333b44444b55555b66666b77777b88888b99999b00000qilei@AFAAW-704030720:~$ cat simple.pl#!/usr/bin/perluse strict;use warnings;my $fileh_pos;open my $fileh,"<", $ARGV[0] or die "error:file can't open";my $line1=<$fileh>;print $line1;my $line2=<$fileh>;print $line2;qilei@AFAAW-704030720:~$ ./simple.pl  test.txta11111a22222qilei@AFAAW-704030720:~$

如下面举例,连续两次读取文件句柄$fileh,发现第二次读取文件句柄【特指while(<$fileh>)】,地址已经递增操作了,而不是从第一行读取test.txt的内容。

qilei@AFAAW-704030720:~$ cat b.pl#!/usr/bin/perluse strict;use warnings;open my $fileh,"<", $ARGV[0] or die "error:file can't open";while(<$fileh>){        if($_ =~ /a33333/) {                print $_;                while(<$fileh>){                        print $_;                }        }}qilei@AFAAW-704030720:~$ ./b.pl test.txta33333a44444a55555a66666a77777a88888a99999a00000b11111b22222b33333b44444b55555b66666b77777b88888b99999b00000

文本多行匹配的一种算法

网上介绍的一种算法,是基于tell和seek。这个在后面会介绍。

这里的算法,可以看做是基于嵌套循环。ps:根据实际需求,可以灵活使用last和next。
如果在第二次while(<$fileh>)的时候增加判断条件,就可以依据第一次匹配关键词“a33333”这个前提条件,做第二次匹配。

qilei@AFAAW-704030720:~$ cat b.pl#!/usr/bin/perluse strict;use warnings;open my $fileh,"<", $ARGV[0] or die "error:file can't open";while(<$fileh>){        if($_ =~ /a33333/) {                print $_;                while(<$fileh>){                        if($_ =~ /7777/) {                                print $_;                                last;                        }                }        }}qilei@AFAAW-704030720:~$ ./b.pl test.txta33333a77777qilei@AFAAW-704030720:~$

seek - reposition file pointer for random-access I/O

定位指针,即记录文件句柄的地址。
可以记录文件句柄的头地址、中间地址、末地址。

seek - perldoc.perl.org
http://perldoc.perl.org/functions/seek.html

tell - get current seekpointer on a filehandle

获取之前定位的指针。

tell - perldoc.perl.org
http://perldoc.perl.org/functions/tell.html

seek和tell一般是配套使用。

下面的例子,包含了seek和tell的用法。而且从另一角度,解释了文件句柄头地址的理解。

例子:连续执行两次while(<$fileh>)的结果

可以看出,第二次执行while(<$fileh>)的时候,文件句柄已经读不出任何内容了。

qilei@AFAAW-704030720:~$ cat test.txta11111a22222a33333a44444a55555a66666a77777a88888a99999a00000b11111b22222b33333b44444b55555b66666b77777b88888b99999b00000qilei@AFAAW-704030720:~$ cat a1.pl#!/usr/bin/perluse strict;use warnings;open my $fileh,"<", $ARGV[0] or die "error:file can't open";while(<$fileh>){        if($_ =~ /3333/) {                print $_;        }}while(<$fileh>){        if($_ =~ /7777/) {                print $_;                last;        }}qilei@AFAAW-704030720:~$ ./a1.pl test.txta33333b33333qilei@AFAAW-704030720:~$

增加tell和seek的使用

tell的作用,是记录文件句柄的头地址,即位置。
seek有三个参数,
1. 文件句柄;
2. 依据第三个参数,提供相对于头地址的相对位置;
3. 如下:
0代表文件开头的位置。即重新开始,类似先close $fileh,然后再open $fileh的效果。
1代表当前头地址的位置;
2代表文件末尾的位置。

qilei@AFAAW-704030720:~$ cat a2.pl#!/usr/bin/perluse strict;use warnings;my $fileh_pos;open my $fileh,"<", $ARGV[0] or die "error:file can't open";while(<$fileh>){        if($_ =~ /3333/) {                $fileh_pos=tell $fileh;                print $_;        }}seek($fileh,$fileh_pos,0);while(<$fileh>){        if($_ =~ /7777/) {                print $_;                last;        }}qilei@AFAAW-704030720:~$ diff a1.pl a2.pl4a5> my $fileh_pos;7a9>               $fileh_pos=tell $fileh;11a14> seek($fileh,$fileh_pos,0);qilei@AFAAW-704030720:~$ ./a2.pl test.txta33333b33333b77777qilei@AFAAW-704030720:~$

参考文档

Perl特殊变量
http://www.yiibai.com/perl/perl_special_variables.html
Perl参考函数
http://www.yiibai.com/perl/perl_function_references.html

0 0