我的代码如下所示。有谁知道我如何测试这个错误或者为什么我会收到这个错误?问题出在第 16 行,即我的代码中 chomp $stringtoFind
: 上面的括号:
#!usr/bin/perl
use strict;
use warnings;
my $syslogFile = 'syslog';
open (my $syslogInfo, '<', $syslogFile) or die "Could not open $syslogFile";
my $keywordFile = 'keyword';
open (my $keywordInfo, '<', $keywordFile) or die "Could not open $keywordFile";
while (my $line = <$syslogInfo>)
{
if(my $stringtoFind =~ <$keywordInfo>)
{
chomp $stringtoFind;
#print "$line\n";
$stringtoFind =~ ( ^/[a-zA-Z][a-zA-Z][a-zA-Z]\s(\d\d)\s(\d\d):(\d\d):(\d\d)\s[a-zA-Z]*\s($stringtoFind).*/s);
open(outputFile, ">>output");
flock(outputFile, 2);
print outputFile "$line\n";
}
}
还有一个问题。我不知道为什么,但我的代码输出的内容与我想要找到的内容非常不同。
在系统日志文件中我有:
Dec 27 21:17:52 osboxes rsyslogd: [origin software="rsyslogd" swVersion="8.12.0" x-pid="695" x-info="http://www.rsyslog.com"] rsyslogd was HUPed
Dec 27 21:18:05 osboxes anacron[634]: Job `cron.daily' terminated
Dec 27 21:18:05 osboxes anacron[634]: Normal exit (1 job run)
Dec 27 21:22:29 osboxes NetworkManager[686]: <info> lease time 1800
Dec 27 21:22:29 osboxes NetworkManager[686]: <info> domain name 'localdomain'
我只想输出关键字中包含 NetworkManager 的任何内容,但却输出不包含 NetworkManager 的内容,这让我很困惑。就目前的情况而言,任何帮助将不胜感激,因为我对 Perl 还很陌生,我陷入了困境。
最佳答案
将正则表达式锚定到行首的正确方法是 ^
作为表达式的第一个字符(即第一个 /
之后)。
$stringtoFind =~ ( /^[a-zA-Z][a-zA-Z][a-zA-Z]\s(\d\d)\s(\d\d):(\d\d):(\d\d)\s[a-zA-Z]*\s($stringtoFind).*/s);
这也是一个错误if(my $stringtoFind =~<$keywordInfo>)
。 =~
是模式匹配运算符。所以这一行没有任何意义,因为它匹配新创建的变量中的字符串,并且 <>
正在从文件句柄读取行,不应该这样使用。
if (defined(my $stringtoFind = <$keywordInfo>))
并且脚本为我编译。
您收到的错误是来自 <$keywordInfo>
的测试。文件中的一行可以是 0
,其计算结果为 false
在 Perl 中。因此,您应该使用 defined
进行测试检查 eof
时.
当您从关键字文件中读取系统日志文件中的每一行时,您的脚本会将系统日志文件中的每一行与关键字文件中的匹配行进行匹配。因此 syslog 的第 3 行将与关键字的第 3 行匹配。如果关键字文件的行数较少,则根本不会匹配该行。这可能不是您想要的。在开始循环之前,最好将关键字文件中的所有行读入数组,然后针对 syslog 文件中的每一行迭代它们。如果您使用类似 Regexp::Assemble 的内容您甚至可以创建一个正则表达式来匹配这些行,因此不需要迭代。
关于regex - <HANDLE> 构造的值可以是 "0";在 perltestscript.pl 第 16 行使用 Defined() 进行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34570232/