要搜索的字符串为:
the file_is being created_automaically {
period=20ns }
我使用的Perl脚本如下(这个脚本对于单行字符串工作正常,但对于多行字符串不工作)
#!/usr/bin/perl
my $dir = "/home/vikas";
my @files = glob( $dir . '/*' );
#print "@files";
system ("rm -rf $dir/log.txt");
my $list;
foreach $list(@files){
if( !open(LOGFILE, "$list")){
open (File, ">>", "$dir/log.txt");
select (File);
print " $list \: unable to open file";
close (File);
else {
while (<LOGFILE>){
if($_ =~ /".*the.*automaically.*\{\n.*period\=20ns.*\}"/){
open (File, ">>", "$dir/log.txt");
select (File);
print " $list \: File contain the required string\n";
close (File);
break;
}
}
close (LOGFILE);
}
}
2条答案
按热度按时间uurity8g1#
此代码未编译,它包含导致其无法执行错误您不应发布未首先尝试运行代码
问题的根源在于,对于多行匹配,你不能以逐行模式读取文件,你必须将整个文件放入一个变量中。然而,你的程序包含许多缺陷。我将演示。以下是你的代码摘录(带有固定的缩进和缺失的大括号)。
首先,始终用途:
这将为您节省许多麻烦和长时间搜索隐藏的问题。
这在Perl中更好,在Perl中可以控制错误:
第一次
在循环本身中声明循环变量,而不是在它之前。
在打印到文件句柄之前,您不必显式地
select
文件句柄。您只需打印到文件句柄:print File "...."
。您所做的只是更改STDOUT文件句柄,这不是一件好事。另外,这是错误日志,应该转到STDERR。这可以通过在程序开始时打开STDERR文件来完成。为什么要这样做?如果你不是在终端调试程序,例如通过Web或其他进程,STDERR不会显示在屏幕上。否则,这只是调试时的额外工作。
这样做的另一个好处是不必先删除日志。现在,您可以这样做:
warn
将转到STDERR,因此它基本上与print STDERR
相同。说到
open
,你应该使用三个参数open和显式的文件句柄,所以它变成:因为你要查找多行匹配,你需要替换为slurp文件。这可以通过将输入记录分隔符设置为undef来完成。通常如下所示:
接下来如何应用正则表达式:
$_ =~
是可选的。如果没有使用其他变量,正则表达式将自动与$_
匹配。你可能不应该在正则表达式中使用
"
。除非你在目标字符串中有"
。我不知道你为什么把它放在那里,也许你认为字符串需要在正则表达式中用引号括起来。如果你这样做了,那就错了。为了匹配上面的字符串,你需要:您不必对
\
大括号{}
或等号=
进行转义。您不必使用引号。/s
修饰符使.
(通配符句点)也匹配换行符,因此我们可以删除\n
。我们可以从字符串开头或结尾删除.*
,因为这是隐含的,正则表达式匹配始终是部分匹配,除非使用了锚点。关键字
break
只用于switch
特性,这是实验性的,而且你没有使用它,或者启用它。所以它只是一个简单的词,这是错误的。如果你想提前退出循环,你可以使用last
。注意,我们不必使用last
,因为我们对文件进行了sloop,所以我们没有循环。另外,你通常应该选择合适的变量名。如果你有一个文件列表,我认为包含文件名的变量不应该被称为
$list
。它被称为$file
是合乎逻辑的。输入文件句柄不应该被称为LOGFILE,它应该被称为$input
,或者$infh
(输入文件句柄)。这是我得到的,如果我把上面的应用到你的程序:
请注意,
print
将转到STDOUT,而不是错误日志。将STDOUT和STDERR放到同一个文件中并不常见。如果需要,可以在shell中重定向输出,如下所示:uqxowvwt2#
下面的示例代码演示了如何使用
logger($fname,$msg)
子例程将regex用于多行情况。代码片段假设输入文件相对较小,可以读入变量
$data
(假设计算机有足够的内存读入)。注意:输入数据文件应与主目录
$ENV{HOME}
中的其他文件区分开来,在此代码示例中,假定这些文件与模式test_*.dat
匹配,也许您不打算 * 扫描 * 主目录中的所有文件(可能有数千个文件,但您只对少数几个感兴趣)引用:正则表达式修改,unlink,perlvar