我发现了一些我可以在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
之前我在文件中每行只有一个字符串并执行了一个简单的测试,例如if ($this_line =~ /$string_to_search_for/i )
,但当我在文件中切换到正则表达式并执行“实时”eval语句时现在获得Can't use string ("") as a subroutine ref while "strict refs" in use at scrub_file.pl line 82
,第82行是if ($rege->($this_line)) {
。
在出现该错误消息之前,我收到了:Use of uninitialized value in subroutine entry at scrub_hhsysdump_file.pl line 82, <$fh>
我对该错误消息有所了解,但似乎无法使perl引擎对我的代码感到满意。
仍然是perl的新手并且总是在寻找指针。提前谢谢。
答案 0 :(得分: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;
}
}
}