0

私はPerlスクリプトを書きました:

#!/usr/bin/perl

use strict;
use warnings;

my $file_name;
my $ext = ".text";
my $subnetwork2;
my %files_list = ();
    opendir my $dir, "." or die "Cannot open directory: $!";
    my @files = readdir $dir;

sub create_files() {

    my $subnetwork;
    open(MYFILE, 'file.txt');
    while (<MYFILE>) {
        if (/.subnetwork/) {
            my @string = split /[:,\s]+/, $_;
            $subnetwork = $string[2];
        }
        if (/.set/ && (defined $subnetwork)) {
            my @string = split /[:,\s]+/, $_;
            my $file = $subnetwork . $string[1];
            open FILE, ">", "$file.text" or die $!;
            close(FILE);
        }
    }
    close(MYFILE);
}

sub create_hash() {
    foreach (@files) {
        if (/.text/) {

            open($files_list{$_}, ">>$_") || die("This file will not open!");

        }
    }
}

sub init() {
    open(MYFILE3, 'file.txt');
    while (<MYFILE3>) {
        if (/.subnetwork/) {
            my @string3 = split /[:,\s]+/, $_;
            $subnetwork2 = $string3[2];
            last;
        }
    }
    close(MYFILE3);
}

sub main_process() {

    init;
    create_files;
    create_hash;

    open(MYFILE1, 'file.txt');
    while (<MYFILE1>) {
        if (/.subnetwork/) {
            my @string3 = split /[:,\s]+/, $_;
            $subnetwork2 = $string3[2];
        }
        if (/.set/) {
            my @string2 = split /[:,\s]+/, $_;
            $file_name = $subnetwork2 . $string2[1] . $ext;
        }
        if (/.domain/ || /.end/ || ($. < 6)) {
            my $domain = $_;
            foreach (@files) {
                if (/.text/ && /$subnetwork2/) {
                    prnt { $files_list{$_} } "$domain";
                }
            }
        }
        elsif ($. >= 6) {
            print { $files_list{$file_name} } "$_";
        }
     }
    close(MYFILE1);
    foreach my $val (values %files_list) { close($val); }
    closedir $dir;
}

main_process;

このスクリプトは、の内容に基づいて現在のディレクトリにファイルを作成し、file.txtそれらのファイルを再度開きます。

次に、処理file.txtを開始し、動的に設定されたファイル名に従って行をリダイレクトします。

このファイル名の設定も、ファイル内のデータに基づいていますfile.txt

ここで私が直面している問題は、リダイレクトが単一のファイルにのみ行われることです。これは、ファイルハンドルに問題があることを意味します。

作成されることが期待されるすべてのファイルは完全に作成されますが、データはそのうちの1つにのみ入ります。

リダイレクト中に使用しているファイルハンドルに問題があるかどうかは疑問です。

誰か助けてもらえますか?サンプル入力ファイルは以下のとおりです。

..cnai #Generated on Thu Aug 02 18:33:18 2012 by CNAI R21D06_EC01, user tcssrpi
..capabilities BASIC
.utctime 2012-08-02 13:03:18
.subnetwork ONRM_ROOT_MO:NETSim_BAG
.domain BSC
.set BAG01
AFRVAMOS="OFF"
AWBVAMOS="OFF"
ALPHA=0
AMRCSFR3MODE=1,3,4,7
AMRCSFR3THR=12,21,21
AMRCSFR3HYST=2,3,3
AMRCSFR3ICM=
AMRCSFR4ICM=
USERDATA=""
.set BAG02
AFRVAMOS="OFF"
AWBVAMOS="OFF"
ALPHA=0
AMRCSFR3MODE=1,3,4,7
AMRCSFR3THR=12,21,21
AMRCSFR3HYST=2,3,3
..end

私が直面している問題は実行中です:

> process.pl 
Use of uninitialized value in ref-to-glob cast at process.pl line 79, <MYFILE1> line 6.
Can't use string ("") as a symbol ref while "strict refs" in use at process.pl line 79, <MYFILE1> line 6.

私が理解できる問題はこの行にあります:

print { $files_list{$_} } "$domain";

でも理由がわからない!!

必要な出力は次のとおりです。

> cat NETSim_BAGBAG01.text 
.set BAG01
AFRVAMOS="OFF"
AWBVAMOS="OFF"
ALPHA=0
AMRCSFR3MODE=1,3,4,7
AMRCSFR3THR=12,21,21
AMRCSFR3HYST=2,3,3
AMRCSFR3ICM=
AMRCSFR4ICM=
USERDATA=""


> cat NETSim_BAGBAG02.text
.set BAG02
AFRVAMOS="OFF"
AWBVAMOS="OFF"
ALPHA=0
AMRCSFR3MODE=1,3,4,7
AMRCSFR3THR=12,21,21
AMRCSFR3HYST=2,3,3
> 
4

3 に答える 3

3

コードのこの部分が重要です。

 open(PLOT,">>$_") || die("This file will not open!");
 $files_list{$_}=*PLOT;

問題は、基本的にファイルハンドルPLOTをグローバル変数として使用していることです。ハッシュ内のすべてのエントリは、この同じファイルハンドルを指しています。次のようなものに置き換えます。

 local *PLOT;
 open(PLOT,">>$_") || die("This file will not open!");
 $files_list{$_}=*PLOT;
于 2012-08-10T11:55:05.997 に答える
3

次の行の問題:

open(PLOT,">>$_") || die("This file will not open!");
$files_list{$_}=*PLOT;

それらを次のものに置き換える必要があります。

open($files_list{$_},">>$_") || die("This file will not open!");
于 2012-08-10T11:41:41.337 に答える
0

あなたはこのプログラムに非常に巻き込まれています。ハッシュテーブルや複数のサブルーチンは必要ありません。

NETSim_BAG.BAG01.textこれは、データを処理し、ファイルとを書き込むコードの簡単なリファクタリングですNETSim_BAG.BAG02.text。名前を少し明確にするために、サブネットとセットの間にドットを入れました。

use strict;
use warnings;

my $out_fh;
open my $fh, '<', 'file.txt' or die $!;
my ($subnetwork, $set, $file);

while (<$fh>) {

    if ( /^\.subnetwork\s+\w+:(\w+)/ ) {
      $subnetwork = $1;
    }
    elsif ( /^\.set\s+(\w+)/ and $subnetwork) {
      $set = $1;
      $file = "$subnetwork.$set.text";
      open $out_fh, '>', $file or die qq(Unable to open "$file" for output: $!);
      print $out_fh;
    }
    elsif ( /^\.\.end/ ) {
      undef $subnetwork;
      undef $file;
    }

    if (/^[^.]/ and $file) {
      print $out_fh $_;
    }
}
于 2012-08-10T12:38:13.223 に答える