2015-06-20 30 views
1

我在這裏展示了一個小樣本Perl腳本部分,如下所示,其中基於許多if-else條件的輸入文件在@final_records中獲取最終輸出。我的問題是如何輕鬆檢測輸入的文件行號,在這段代碼中被拒絕,並可能將這些行放在單獨的新文件中?獲取未輸入最終輸出的輸入文件的行號

while (<MY_INP_FILE>) { 
    chomp; 
    next if $_ =~ /^(NAME)/; 
    ( $secname,  $id_my_sec_num_des, 
     $my_source,  $id_my_sec_num_src, 
     $id_my_unique, $security_typ, 
     $my_sector_des, $id_my_global, 
     $composite_id_my_global, 
    ) = split(/\|/, $_); 

    if (exists $trexcp{$id_my_global}) { 
     $my_match_ticker = $trexcp{$id_my_global}; 
    } 
    else { 

     $ticker   = $id_my_sec_num_des; 
     $my_match_ticker = $id_my_sec_num_des; 

     if ($my_sector_des eq "BSE") { 
      ($indx_tick, $indx_val) = split(' ', $id_my_sec_num_des); 
      $my_match_ticker = $indx_tick; 

     } 
     elsif ($my_sector_des eq "PFD" || $my_sector_des eq "COMP") { 
      ($base_ticker, $div_percent, $matdt, $series) 
       = split(" ", $id_my_sec_num_des); 

      if (length($base_ticker) > 3) { 
       $base_tick = substr($base_ticker, 0, 3); 
      } 
      else { $base_tick = $base_ticker; } 

      if ($my_sector_des eq "PFD" && $matdt ne "") { 
       $series =~ s /([A-Z])([A-Z])/$2/; 
       $my_match_ticker = $base_tick . ".PR" . $series; 
      } 

     } 
     elsif ($my_sector_des eq "EQ") { 

      if ($my_source =~ m/^(BD|IN|MM|KS|KF|SP)$/) { 
       if ($my_source eq "MM") { 
        $my_match_ticker =~ s/(\s+)/ /g; 
        @mm_tick = split(' ', $my_match_ticker); 

        if ( ($my_match_ticker !~ /\*/) 
         && ($#mm_tick eq 2) 
         && ($mm_tick[2] ne " ")) 
        { 
         $my_match_ticker = "$mm_tick[0]" . "$mm_tick[2]"; 
        } 
        $my_match_ticker =~ s/\*|\///g; 
       } 
      } 
      elsif (($my_source eq "HK") 
       && (length($id_my_sec_num_des) < 4)) 
      { 
       if ($id_my_sec_num_des =~ m/^(\d\d\d)$/) { 
        $my_match_ticker 
         =~ s/$id_my_sec_num_des/0$id_my_sec_num_des/; 
       } 

      } 

     } 
    } 

    $final_my_records = join(
     "|", 
     ( $id_my_global,   $id_my_sec_num_src, 
      $id_my_unique,   $secname, 
      $id_my_sec_num_des,  $my_source, 
      $security_typ,   $my_sector_des, 
      $composite_id_my_global, $my_match_ticker 
     ) 
    ); 

    push @final_records, "$final_my_records\n"; 

} 

回答

1

$. variable

  • HANDLE->input_line_number(EXPR)
  • $INPUT_LINE_NUMBER
  • $NR
  • $.

用於訪問的最後一個文件句柄的當前行號。

Perl中的每個文件句柄都計算從中讀取的行數爲 。 (取決於$/價值,什麼 Perl的想法構成了行可能不符合你的。)當線從 一個文件句柄(通過readline()<>)讀取,或者當tell()seek()上調用它,$.成爲該文件句柄的行計數器 的別名。

可以通過分配到$.調整計數器,但這不會 實際移動查找指針。本地化$.將不會本地化 文件句柄的行數。相反,它將本地化​​perl的 概念,其中文件句柄$.目前是別名。

$.復位時,文件句柄是封閉的,而不是在一個開放的文件句柄 是中間沒有close()重新開放。有關更多 的詳細信息,請參閱perlop中的「I/O操作員」。由於<>從未做過明確關閉,所以在ARGV文件中行數增加(但請參閱 中的eof中的示例perlfunc)。

您還可以使用HANDLE->input_line_number(EXPR)訪問 行計數器對於給定的文件句柄,而不必擔心 它處理你上次訪問。

助記符:許多程序使用.來表示當前行號。

添加記錄push @final_records, "$final_my_records\n";的代碼不屬於所有意大利式麪條if-else代碼。這意味着被拒絕記錄的唯一地方是next if $_ =~ /^(NAME)/;。因此,請執行以下操作:

if (/^(NAME)/) { 
    ... # put your code here 
    next; 
} 
+0

..如果(/ ^(NAME)/)已被用來通過文件的標題行。我想到了一種新的方法。我會打印「$。,\ n」;在chomp後面並填充數組1。然後就在$ final_my_records = join之前(我會再放一個打印「$。,\ n」;然後填入一個數組2,array1(所有行)和2(所選行)的區別應該是被拒絕的行號。是否同意/幫助此構造? – pmr

+0

對所有通過'/ ^(NAME)/'測試的行執行'push'操作,我不理解你,沒有任何其他代碼會跳過行 –

+0

@Hynek ...先生,我剛剛發佈了代碼片段,所以可能存在{}相關的錯誤,事實是,如果輸入文件有100000行輸出是80000行,我需要那些20000行用於分析目的無論如何感謝您的幫助,我已經接受您的答案,我的想法正在工作。 – pmr