• perl一次读取多行文本的策略


    在处理文本时,经常遇到这种情况:就是我们须要把两行文本做一个比較,然后选择性输出。

    而在while(<FILEHAND>){do something}程序块中默认仅仅能一次读取一行。笔者在这里,举一个简单的样例来说明怎么处理这种情况。

    有一个这样一段文本:

    a 1 2 3 4
    a 5 6 7 8
    a 6 7 8 9
    a 7 8 9 11
    a 7 8 9 12
    a 13 12 14 15
    a 18 14 16 17
    a 2 3 4 65


    要求是这种:假设上一行的第5列数字大于下一行第二列的数字。就把这两行都输出。

    策略一:把输入文本存放到数组中,然后利用for循环,一次输出两行做推断。

    脚本例如以下:

    #! /usr/bin/perl -w
    use strict;
    chomp(my @a=<DATA>);
    my @out;
    for(my $i=0;$i<$#a;$i++){
            my ($a1,$a2)=(split/s+/,$a[$i])[1,4];
            my ($b1,$b2)=(split/s+/,$a[$i+1])[1,4];
            push @out,@a[$i,$i+1]  if $a2 > $b1;
    }
    my %ha;
    my @new=grep {$ha{$_}++<1}@out;
    print $_,"
    " for@new;
    __DATA__
    a 1 2 3 4
    a 5 6 7 8
    a 6 7 8 9
    a 7 8 9 11
    a 7 8 9 12
    a 13 12 14 15
    a 18 14 16 17
    a 2 3 4 65

    策略一思路比較简单,可是假设输入文本过大。比較消耗内存。

    当然使用Tie::File模块又是另外一回事情了。

    在这里,笔者利用tell和seek函数,对句柄定位做一下调整,就能够在while循环中。实现一次输出多行。一行多次输出了,是不是非常方便呢?

    代码例如以下:

    #! /usr/bin/perl -w
    use strict;
    my @out;
    while(<DATA>){
            chomp;
            my $pos=tell(DATA);
            my @a=split/s+/,$_;
            my $sec=<DATA>;
            if($sec){
                    chomp$sec;
                    my @b=split/s+/,$sec;
                    if($a[4]>$b[1]){
                            push @out,$_,$sec;
                    }
            }
            seek(DATA,$pos,0);
    }
    my %ha;
    my @new=grep $ha{$_}++ < 1,@out;
    print $_,"
    " for@new;
    __DATA__
    a 1 2 3 4
    a 5 6 7 8
    a 6 7 8 9
    a 7 8 9 11
    a 7 8 9 12
    a 13 12 14 15
    a 18 14 16 17
    a 2 3 4 65


    程序执行的结果例如以下:

    a 5 6 7 8
    a 6 7 8 9
    a 7 8 9 11
    a 7 8 9 12
    a 18 14 16 17
    a 2 3 4 65


    __结束__

  • 相关阅读:
    Vmware Workstation的虚拟机如何通过宿主机的无线网卡和外部通信
    docker知识点扫盲
    typescript
    日报10
    日报8
    日报9
    SQL 没有分隔符的日期处理(比如20220101)
    Unreal中关于颜色的技术分享
    实名认证
    uniapp
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/6795580.html
Copyright © 2020-2023  润新知