0

我有一堆 18MB 的文本文件,我需要在 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";
4

3 回答 3

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”为后缀命名。

于 2012-08-07T12:54:41.037 回答
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);
}

我的时间比较少,所以我无法检查任何打字错误,希望您了解它是如何完成的。

于 2012-08-09T18:35:11.893 回答
0

假设你有一个目录中的所有文件(可能是'/home/user/tmp'),你可以将你的代码嵌入到一个由目录读取程序调用的函数'process'中:

#!/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;
于 2012-08-07T14:09:03.713 回答