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

我在这里面临的问题是重定向只到一个文件。这意味着文件句柄存在一些问题。

预期创建的所有文件都已完美创建,但数据仅进入其中一个。

我怀疑我在重定向时使用的文件句柄是否有问题。

有人可以帮忙吗?示例输入文件如下:

..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;

您应该将它们替换为:

open($files_list{$_},">>$_") || die("This file will not open!");
于 2012-08-10T11:41:41.337 回答
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 回答
0

你已经让自己非常纠结于这个程序。不需要哈希表或多个子例程。

这是对您的代码的快速重构,该代码适用于您的数据并写入文件NETSim_BAG.BAG01.textNETSim_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 回答