在perl数组中打开多个文件

时间:2015-06-15 03:37:45

标签: arrays perl

我有一个perl脚本,我将所有带有.log扩展名的文件分配给名为@allfiles的数组。如何为存储在每个阵列中的文件运行我的脚本?我的想法类似open(my $fn, '<', @allfiles) or die "Could not open file '@files': $!";,但这不正确,因为它会立即读取数组中的所有文件。有什么帮助吗?

#!/usr/bin/perl

use strict;
use warnings;
use POSIX 'strftime';

#my $filename = 'IGXLEventLog.3.17.2015.20.25.12.625.log';
my $directory = "/opt/lampp/htdocs/otpms/Data";
my @allfiles = glob("*.log");
opendir (my $dir, $directory) or die "Could not open directory '$directory': $!";
open(my $fn, '<', $filename) or die "Could not open file '$filename': $!";

our @output;
my %details;

    captureData();

close ($fn);

my $timestamp = strftime '%Y-%m-%d.%H:%M:%S', localtime;
@output = $timestamp .'.sql';
open(my $fh, '>', @output) or die "Could not create file '@output': $!";

    createFile();

close($fh);

sub captureData
{
    while(my $row = <$fn>)
    {
        chomp $row;

        if ($row =~ /Computer Name:\s*(\S+)/i ) # match computer name with white space then non white space
        {
            $details{tester_name} = $1;
        }
        elsif ($row =~ /Operating System:\s*(.*\S)/i ) # match operating system with white space then any word
        {
            $details{op_sys} = $1;
        }
        elsif ($row =~ /IG-XL Version:\s*([^;]*)/i ) # match ig-xl version with white space then semi colon
        {
            $details{igxl_vn} = $1;
        }
        elsif ($row =~ /^([\d.]+)\s+(\S+)(?=\s)/ ) #match slot with white space and then non white space
        {
            push @{$details{slot}}, $1;
            push @{$details{board_name}},  $2;
        }
    }
} # captureData

sub createFile
{
    my $log_time_stamp = (stat($filename))[9];
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime($log_time_stamp);
    my $nice_timestamp = sprintf ( "%04d-%02d-%02d %02d:%02d:%02d",
                                   $year+1900,$mon+1,$mday,$hour,$min,$sec);
   print $nice_timestamp;

    for (my $i = 0; $i < @{$details{slot}}; $i++)
    {
    print {$fh}
        "INSERT INTO TesterDeviceMatrix.TBL_TESTER_INFO"
        ."(tester_name, operating_system, version, board_name, config , date_modified, log_created) "
        ."VALUES ('$details{tester_name}', '$details{op_sys}', '$details{board_name}[$i]', "
        ."'$details{igxl_vn}', '$details{slot}[$i]', '$timestamp', '$nice_timestamp');\n";
    }
} # createFile

1 个答案:

答案 0 :(得分:2)

您只需要在循环中包含处理单个文件的代码,该循环遍历所有日志文件

您还应该重新考虑您使用的评论数量。编写代码并选择标识符要好得多,以便行为不言自明。在子程序中包装部分过程也是适得其反的

这就是我实现你的问题的方法。除非编译

,否则我无法测试
#!/usr/bin/perl

use strict;
use warnings;
use 5.010;
use autodie;

use File::stat;
use Time::Piece;

use constant LOG_DIR => '/opt/lampp/htdocs/otpms/Data';
use constant COLUMNS => qw/ tester_name operating_system version board_name config date_modified log_created /;

my $now_timestamp = localtime->strftime('%Y-%m-%d.%H:%M:%S');
open my $out_fh, '>', "$now_timestamp.sql";

chdir LOG_DIR;

while ( my $logfile = glob '*.log' ) {

    warn "Processing $logfile\n";

    open my $log_fh, '<', $logfile;

    my %details;

    while ( <$log_fh> ) {

        if ( /Computer Name:\s*(\S+)/i ) {
            $details{tester_name} = $1;
        }
        elsif ( /Operating System:\s*(.*\S)/i ) {
            $details{op_sys} = $1;
        }
        elsif ( /IG-XL Version:\s*([^;]*)/i ) {
            $details{igxl_vn} = $1;
        }
        elsif ( /^([\d.]+)\s+(\S+)/ ) {
            push @{ $details{slot} }, $1;
            push @{ $details{board_name} }, $2;
        }
    }

    my $stat          = stat $logfile;
    my $log_timestamp = localtime($stat->mtime)->strftime('%Y-%m-%d %H:%M:%S');

    for my $i ( 0 .. $#{ $details{slot} } ) {

        my @values = (
            $details{tester_name},
            $details{op_sys},
            $details{board_name}[$i],
            $details{igxl_vn},
            $details{slot}[$i],
            $now_timestamp,
            $log_timestamp,
        );

        printf {$out_fh} "INSERT INTO TesterDeviceMatrix.TBL_TESTER_INFO (%s) VALUES (%s);\n",
            join(', ', COLUMNS),
            join(', ', map "'$_'", @values);
    }
}

close $out_fh;