2012-08-07 69 views
0

我有一堆18MB的文本文件,需要在Perl中读取,提取特定信息并将其写入每个文件的新文件。如何在Perl中读取多个文件并创建包含这些文件中数据的不同文件

我该怎么做?

例如,下面的代码只适用于一个文件,并为代码中提到的文件创建一个新文件,但是我怎么能在多个文件上执行它,因为我有很多文件?

以下是我的代码,它只适用于单个文件。我想为许多文件做同样的事情。我该怎么做?

use Regexp::Common qw/net/; 
use Regexp::Common qw/net/; 

system("clear"); 

my $file2 = 'TR1'; 
open my $in, '<', $file2 or die $!; 
open my $out, '>', 'Number_of_Hops_TR1_007' or die $!; 

my $var = 0; 
my $i = 0; 
my $traceroute; 
my $line; 

while (my $line = <$in>) { 

    if ($line =~ /^traceroute to (\S+)/) { 
     $traceroute = $1; 
     $var++; 

     #print "$traceroute\n"; 
    } 
    my ($ip) = $line =~ /(?: \d+ \s \s+) ($RE{net}{IPv4}) /msx; 

    if ($traceroute eq $ip) { 

     print $out $ip if defined, "\n"; 
     if ($ip ne undef) { 
      { $i++; } 
     } 
    } 
    else { 
    } 
} 

print $out "Number of traceroutes - $var\n"; 

print $out "Number of traceroutes reached destination - $i\n"; 

my $subs = $var - $i; 

print $out 
    "Number of traceroutes that did not reaach destination ($subs)\n"; 

my $perc = ($i/$var) * 100; 

print $out "Percentage of sucessful traceroutes ($perc%)\n"; 

回答

3

的一般方法可能是这样的:

#!/usr/bin/env perl 
use strict; 
use warnings; 
my $prev = q(); 
my ($fh, $log); 
while (<>) { 
    if ($ARGV ne $prev) { 
     $prev = $ARGV; 
     $log = $ARGV . '.log'; 
     open $fh, '>', $log or die "Can't open '$log': $!\n"; 
    } 
    if (m/^traceroute to (\S+)/) { 
     print {$fh} $1, "\n"; 
    } 
} continue { 
    close $fh if eof; 
} 

输出文件根据与“.LOG”为后缀的输入名字干脆就叫。

+0

我不知道这将如何适合我的代码,请任何帮助,因为当我运行程序,它只是继续运行 – user1581917 2012-08-07 18:07:41

+0

如果脚本被称为'test.pl'那么你会运行它通过名称您想要解析的文件为其参数:'test.pl file1 file2 file3 ...'您的代码对一个输入文件进行硬编码。这个想法是将其改变为处理多个文件的循环。 – JRFerguson 2012-08-07 18:42:28

0

假设你有一个目录中的所有文件(可能是“/ home/user中/ tmp目录”),你可以嵌入在一个函数“过程”由目录阅读程序调用代码:

#!/usr/bin/perl -w 

use strict; 

my @files = </home/user/tmp/*>; 

foreach (@files) { 
    if (-f $_) { 
    process ($_); 
    } 
} 

sub process { 
    my $file2 = $_[0]; 
    open my $in, '<', $file2 or die $!; 
    open my $out, '>', "$file2.log" or die $!; 

    # ... your remain code here 
} 

否则,您可以创建一个要编辑的文件列表(假设在'filelist.txt'中),每行有完整的路径信息和一个文件名,并使用以前的相同代码加载到'@files':

open LIST, "<filelist.txt" or die; 
my @files = <LIST>; 
close LIST; 
+0

对不起,但我仍然无法加入与我自己的代码,尤其是与文件名和所有 – user1581917 2012-08-07 18:16:21

+0

我更新代码与操作为开放读取和写入文件。 – 2012-08-08 00:59:32

+0

@Jamie其实我试过上面的代码,但它不能正常工作我插入我的代码完全从while循环开始直到我的while循环结束......实际上没有发生......我添加了以下代码 – user1581917 2012-08-09 19:33:46

1
@txt_files =(); 
@useful_files =(); 

opendir(hand,"directory/with/txt/files");#eg: on windows opendir(hand,"c:/txtdir"); 
@files = readdir(hand); 
closedir(hand); 

foreach(@files){ 
    if(/\.txt$/i) {      #if the filename has .txt at the end 
    push(@txt_files,$_); 
    } 
} 

foreach(@txt_files) { 
    $txt_file=$_;  
    open(hanr,$txt_file); 
    @lines=(); 
    @lines=<hanr>; 

    foreach(@lines){ 
    if(/^somebeginstuff/i) {    #if you are searching txt files that begin with somebeginstuff 
     push(@useful_files, $txt_file) 
    } 
    } 
} 
close(hanr); 

如果要提取每个txt文件有用行,你可以创建一个哈希,存储 - $ filename-的关键和 - @ arrayofusefullines-的价值,你可以问,如果你不知道

将这样的功能随着push(@useful_files, $txt_file)

但是,如果你想@useful_files的所有内容存储在一些其它的文件,这样做

foreach(@useful_files){ 
    open(hanr,$_); 
    @lines=(); 
    @lines=<hanr>;       #lines are saved now, they just have to be written 
    close(hanr); 
    @parts = split('.', $_); 
    $filenamewithouttype = @parts[0]; 

    open(hanw,$filenamewithouttype."\.dat");#hanw will be used for writing in new .dat files 
    print hanw @lines; 
    close(hanw); 
} 

我有更少的时间,所以我不能检查任何打字错误,希望你能明白它是如何完成的。

+0

**请将其标为答案或UPVOTE ** – GLES 2012-08-12 08:14:09

+0

**请将其标为答案或UPVOTE ** – GLES 2012-08-12 08:14:36

+0

upvote :) :) :) – GLES 2013-01-21 11:12:11

相关问题