0

perlmonks.org( http://www.perlmonks.org/?node_id=870806 )で使用できるものを見つけましたが、動作させることができません。

問題なくファイルを読み取って配列を作成できます。次に、配列の各インデックス(各正規表現)をファイルの各行と比較し、一致した行の前の行と後の行を出力します。

私のコード:

# List of regex's.  If this file doesn't exist, we can't continue
open ( $fh, "<", $DEF_FILE ) || die ("Can't open regex file: $DEF_FILE");
while (<$fh>) {
    chomp;
    push (@bad_strings, $_);
}
close $fh || die "Cannot close regex file: $DEF_FILE: $!";

$file = '/tmp/mydirectory/myfile.txt';
eval { open ( $fh, "<", $file ); };
if ($@) {
      # If there was an error opening the file, just move on
      print "Error opening file: $file.\n";
} else {
      # If no error, process the file
      foreach $bad_string (@bad_strings) {
              $this_line = "";
              $do_next = 0;
              seek($fh, 0, 0); # move pointer to 0 each time through
              while(<$fh>) {
                      $last_line = $this_line;
                      $this_line = $_;
                      my $rege = eval "sub{ \$_[0] =~ $bad_string }"; # Real-time regex
                      if ($rege->( $this_line )) {                    # Line 82
                             print $last_line unless $do_next;
                             print $this_line;
                             $do_next = 1;
                      } else {
                             print $this_line if $do_next;
                             $last_line = "";
                             $do_next = 0;
                      }
              }
      }
}  # End "if error opening file" check

これは、ファイルに1行あたりの文字列だけがあり、次のような簡単なテストを実行しif ($this_line =~ /$string_to_search_for/i )たときに機能していましたが、ファイルの正規表現と「リアルタイム」評価ステートメントに切り替えると、Can't use string ("") as a subroutine ref while "strict refs" in use at scrub_file.pl line 8282行目がになりif ($rege->($this_line)) {ます。

そのエラーメッセージの前に、私は受け取っています:Use of uninitialized value in subroutine entry at scrub_hhsysdump_file.pl line 82, <$fh> 私はそのエラーメッセージをある程度理解していますが、これまでのところ、perlエンジンを私のコードに満足させることができないようです。

perlはまだ新しく、常にポインタを探しています。前もって感謝します。

4

1 に答える 1

2

私はそれらのステートメントの理由をeval理解できません-彼らがしているように見えるのは、コードをはるかに複雑にし、デバッグを困難にすることだけです。

しかし、文字列に構文エラーがあるために機能していない$regeため、undefです。eval "sub{ \$_[0] =~ $bad_string }"何が含まれているのかわかりませんが$DEF_FILE、適切に区切られた正規表現がない限り、文字列に区切り文字を追加する必要がありevalます。

my $rege = eval "sub{ \$_[0] =~ /$bad_string/ }"

動作する可能性がありますが、の文字列に正規表現メタ文字が含まれていて、それらをリテラル文字として処理する/\Q$bad_string/場合は、代わりに必要になることがあります。$DEF_FILE

eval私はあなたのプログラムのこのバージョンを提案します。それはあなたが電話の大騒ぎなしであなたが必要とすることをするようです。

use strict;
use warnings;

use Fcntl ':seek';

my $DEF_FILE = 'myfile';

my @bad_strings = do {
  open my $fh, '<', $DEF_FILE or die qq(Can't open regex file "$DEF_FILE": $!);
  <$fh>;
};
chomp @bad_strings;

my $file = '/tmp/mydirectory/myfile.txt';

open my $fh, '<', $file or die qq(Unable to open "$file" for input: $!);

for my $bad_string (@bad_strings) {

  my $regex = qr/$bad_string/;

  my ($last_line, $this_line, $do_next) = ('', '', 0);

  seek $fh, 0, SEEK_SET;

  while (<$fh>) {

    ($last_line, $this_line) = ($this_line, $_);

    if ($this_line =~ $regex) {
      print $last_line unless $do_next;
      print $this_line;
      $do_next = 1;
    }
    else {
      print $this_line if $do_next;
      $do_next = 0;
    }
  }
}
于 2013-01-10T21:33:40.310 に答える