2012-11-19 138 views
1

我有一個文件,我想從中讀取數據。這是數據的一個樣本:從文件中讀取兩行數據

NODELOAD   28  27132 3.29108E+04 7.94536E+04 0.00000E+00 
NODELOAD   29  27083 9.89950E+04 9.89950E+04 0.00000E+00 
NODELOAD   29  27132 6.08112E+04 6.08112E+04 0.00000E+00 
NODELOAD   30  27083 1.29343E+05 5.35757E+04 0.00000E+00 
NODELOAD   30  27132 7.94536E+04 3.29108E+04 0.00000E+00 
NODELOAD   31  68 4.80185E+04 -5.47647E+04 -1.17033E+04 
           -1.27646E+03 1.18350E+04 -2.03885E+03 
NODELOAD   31  1114 1.20706E+05 -3.31323E+04 -7.17280E+04 
           2.28198E+03 2.75582E+04 5.74460E+02 

我有這樣的代碼和我能夠讀取單個行的所有值,並將它們保存到一個數組:

foreach my $line (@input) { 
    if($line =~ /^\s*NODELOAD\s+/i) { 
     $line =~ s/^\s*//; 
     @a = split(/\s+/,$line); 

     $modelData{"NODELOAD"}->{$a[1]}->{$a[2]}->{"Fx"} = $a[3]; 
     $modelData{"NODELOAD"}->{$a[1]}->{$a[2]}->{"Fy"} = $a[4]; 
     $modelData{"NODELOAD"}->{$a[1]}->{$a[2]}->{"Fz"} = $a[5]; 

不過,也有一些「 NODELOAD「定義在文件中定義在兩行上,並且具有6個加載值而不是3(每行上的前兩個數字是標識符,以下3/6是數據)。

是否最簡單的寫一個if語句,如果下面一行不是以「NODELOAD」開頭幷包含數字,它將保存數據?文本文件中此部分之後的最後一行不會包含任何數字,但可能是空白或包含文本。

回答

1

是的,最簡單的方法是將先前調用的值保留在某個變量中,然後如果if(/NODELOAD/)不匹配,則只會得到3個值,並使用上一行(以及之前的查看迭代)中的標識符處理它們。你也可以跳過if一個正則表達式,並檢查分裂結果的第一個元素:

my @last_values; 
foreach my $line (@input) { 
    $line =~ s/^\s+//; 
    my @values = split(/\s+/, $line); 
    if($values[0] ne 'NODELOAD') { 
     unshift(@values, @last_values[0..2]); # Get first 3 values from previous call 
     # Then process it however you'd like to 
     $modelData{"NODELOAD"}->{$values[1]}->{$values[2]}->{"Fx2"} = $values[3]; 
    } 
    elsif { 
     # process like previously... 
     $modelData{"NODELOAD"}->{$values[1]}->{$values[2]}->{"Fx"} = $values[3]; 
     $modelData{"NODELOAD"}->{$values[1]}->{$values[2]}->{"Fy"} = $values[4]; 
     $modelData{"NODELOAD"}->{$values[1]}->{$values[2]}->{"Fz"} = $values[5]; 
     @last_values = @values; # and save for future reference 
    } 
} 
+0

這看起來不錯,但是我應該指出的是,我從閱讀文件包含很多其他的數據,以及,所以我仍然需要初始的'if($ line =〜/^\ s * NODELOAD \ s +/i){'代碼,否則它會拿起其他的數據 –

+0

我用你的方法解決了它。謝謝! –