2012-08-10 75 views
0

我寫了一個Perl腳本:的Perl script.file處理問題

#!/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 
> 
+0

關於你的新問題*在ref-to-glob cast *中使用未初始化的值。在你顯示的代碼中沒有第96行,所以我們不能真正幫助正確,但是錯誤幾乎肯定是因爲你在'%files_list'哈希中有一個未定義的元素值。你的代碼非常複雜,閱讀起來很尷尬,我已經給你一個可以理解的工作選擇,幾乎佔你所需的四分之一。它產生你說你想要的確切輸出。請使用它。 – Borodin 2012-08-10 14:36:28

+0

@ Borodin.I已粘貼實際代碼 – Vijay 2012-08-10 16:52:25

+0

您也更改了您要報告的錯誤。這是因爲你'%files_list'哈希中的一個元素的值爲''「' - 一個空字符串。這是一場瘋狂的追逐。請扔掉這個混亂,並使用我給你的工作程序,解決了27行 – Borodin 2012-08-10 17:24:39

回答

3

你在下面幾行的問題:

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

您應該替換他們:

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

謝謝你是正確的 – Vijay 2012-08-10 11:53:22

+0

它是成功的.. – Vijay 2012-08-10 11:54:54

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; 
+1

感謝丹的信息。 – Vijay 2012-08-10 12:00:48

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 $_; 
    } 
} 
+0

我已經粘貼了實際的代碼。 – Vijay 2012-08-10 16:54:42