Perl,多个文件中的多个匹配字符串

时间:2018-07-13 10:35:33

标签: perl

我想使用

 myscript.pl targetfolder/* > result.csv

从多个ASCII文件中获取一些数字。

数据表就像

  

| 44.2 | 3123.7 | 3123 |
  + -------- + -------- + -------- +

->这是数据表的结尾,就像

myscript.pl

#!/usr/bin/env perl

use warnings;
use strict;
use Data::Dumper;  # for debugging

$Data::Dumper::Useqq=1;

#####start######

Title1();
Title2();

print "\n"; 

#####Grep#######

foreach my $currentfile (@ARGV) {     # ARGV is the target files list
    print Dumper($currentfile);       # debug
    open my $filehanlder, '<', $currentfile or die "$currentfile: $!";   

    while ($r <= $#fswf) {      #judge end of the open file
        Value1();
        Value2();
        Print1();
        Print2();
        print "\n";             
        $r++;
    }                 #go next line output

    Close $filehanlder; 
}

#####sub#######
sub Title1 {
    print "title1,title2";
}

sub Title2{
    print "title5,title6,title7,title8";
}


sub Value1 {
    my ($line);
    while ($line = <$filehanlder>)) {
        if ($line =~ /^\|\sMachine\:(\S+)\s+Release\:(\S+)\s+/) {
            our ($machine) = $1;our ($sw) = $2;
        }
    }
}


sub Value2 {
    my ($line);
    while ($line = <$filehanlder>)) {
        if ($line =~ /^\|\sProduction\sResult\s+\|\s(\S+)\s+\|/) {
            next if 1..4;
            my (@b) = "";
            $r = 1
            @result1 = @result2 = @result3 = @result4 = "";

            while ($line !~ /\+\-/) {                                 
                chomp $line; 
                @b = split / *\| */, $line;
                our ($result1[$r]) = $b[1];
                our ($result2[$r]) = $b[2];
                our ($result3[$r]) = $b[3];
                our ($result4[$r]) = $b[4];
                $r++;
                $line = (<$filehanlder>);
                @b = "";
            }
        }
    }
}

##I need a value as file counter, but not sure where to put it.

Sub Print1 {
    print "$machine,$sw,";   # this keeps same cross lines from same file
}

Sub Print2 {
    print "$result1[$r],$result2[$r],$result3[$r],$result4[$r],";  # change every line    
}

#####sub#######

我不知道将$ filehander传递到子例程并通过其他子例程传递的正确方法。

@Dave Cross:感谢您指出。就像你说的那样。如果我在子例程中循环,那么一个子例程将转到文件末尾,其他子例程什么也没有。那我该在主循环中做while吗?还是我应该在每个子例程中打开?因此我可以在每个子例程中将文件处理程序重置为文件的第一行。如果我在子values2中有多个@result作为grep,我该如何使用这些@result的最大行数来打印它们。例如,我有@ result5 [7],@ result6 [12],所以我想打印12行记录,前7行带有result5 grep结果,最后5行,result5列保持空白,而result6列继续打印

1 个答案:

答案 0 :(得分:1)

您的文件句柄仅存储在标量变量($filehanlder)中,因此可以将其与其他变量完全一样地传递到子例程中。

some_subroutine($filehanlder);

然后,在子例程中:

sub some_subroutine {
  my ($fh) = @_;

  # do something with $fh
}

但是我认为您还有更严重的问题要担心。您有两个子程序,其中有一个while (<$filehanlder>)循环。其中第一个将被调用到文件的末尾,而第二个将没有数据要处理。

您可能想重新考虑这段代码的设计。