0

Perl で読み取り、特定の情報を抽出し、それらのファイルごとに新しいファイルに書き込む必要がある 18 MB のテキスト ファイルがたくさんあります。

これどうやってするの?

たとえば、次のコードは 1 つのファイルにのみ適用され、コードに記載されているファイルの新しいファイルを作成しますが、複数のファイルがあるため、複数のファイルに対してそれを行うにはどうすればよいですか?

以下は、単一のファイルでのみ機能する私のコードです。多くのファイルに対して同じことをしたい。どうすればいいですか?

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
}

それ以外の場合は、完全なパス情報と各行に 1 つのファイル名を使用して、編集するファイルのリスト (「filelist.txt」としましょう) を作成し、前と同じコードを使用して「@files」にロードできます。

open LIST, "<filelist.txt" or die;
my @files = <LIST>;
close LIST;
于 2012-08-07T14:09:03.713 に答える