搜索模式中包含多个单词的字符串

时间:2015-06-22 01:34:53

标签: perl

我的程序正在尝试从目录中的多个文件中搜索字符串。代码会搜索perl等单个模式,但无法搜索Status Code 1之类的长字符串。

您能告诉我如何搜索包含多个单词的字符串吗?

#!/usr/bin/perl

my @list = `find /home/ad -type f -mtime -1`;

# printf("Lsit is $list[1]\n");

foreach (@list) {

    # print("Now is : $_");

    open(FILE, $_);
    $_ = <FILE>;
    close(FILE);

    unless ($_ =~ /perl/) { # works, but fails to find string "Status Code 1"
        print "found\n";

        my $filename = 'report.txt';
        open(my $fh, '>>', $filename) or die "Could not open file '$filename' $!";
        say $fh "My first report generated by perl";
        close $fh;

    } # end unless

} # end For

3 个答案:

答案 0 :(得分:1)

您的代码存在许多问题

  • 必须始终 use strictuse warnings位于每个Perl程序的顶部。在没有my的情况下strict显示任何内容都没有什么意义

  • find命令返回的行最后会有一个换行符,必须在Perl找到文件之前将其删除

  • 您应该使用词汇文件句柄my $fh而不是FILE)和open的三参数形式,就像使用输出文件

  • $_ = <FILE>仅将文件的第一行行读入$_

  • unless ($_ =~ /perl/)是反转逻辑,没有必要指定$_,因为它是默认值。你应该写if ( /perl/ )

  • 除非您的程序顶部有say,否则您无法使用use feature 'say'(或use 5.010,这会添加Perl v5.10中提供的所有功能)< / p>

最好避免使用shell命令,因为Perl能够使用命令行实用程序执行任何操作。在这种情况下,-f $file是一个测试,如果文件是普通文件,则返回 true -M $file返回自文件修改时间以来的(浮点)天数< / p>

这就是我编写程序的方式

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

for my $file ( glob '/home/ad/*' ) {

    next unless -f $file and int(-M $file) == 1;

    open my $fh, '<', $file or die $!;

    while ( <$fh> ) {

        if ( /perl/ ) {

            print "found\n";

            my $filename = 'report.txt';
            open my $out_fh, '>>', $filename or die "Could not open file '$filename': $!";
            say $fh "My first report generated by perl";
            close $out_fh;

            last;
        }
    }

}

答案 1 :(得分:0)

更改

unless ($_ =~ /perl/) {

为:

unless ($_ =~ /(Status Code 1)/) {

我确信上述作品,除了它区分大小写。 既然你对它提出质疑,我就重写了你的脚本,以便更好地了解你正在努力完成的事情,并实施上述建议。如果我错了,请纠正我,但是你正试图制作一个匹配&#34;状态代码1&#34;在一堆文件中,在1天内最后修改,并将文件名打印到文本文件。 无论如何,以下是我的建议:

#!/usr/bin/perl

use strict;
use warnings;

my $output_file = 'report.txt';
my @list = `find /home/ad -type f -mtime -1`;

foreach my $filename (@list) {
        print "PROCESSING: $filename";
        open (INCOMING, "<$filename") || die "FATAL: Could not open '$filename' $!";
        foreach my $line (<INCOMING>) {

                if ($line =~ /(Status Code 1)/) {
                        open( FILE, ">>$output_file") or die "FATAL: Could not open '$output_file' $!";
                        print FILE sprintf ("%s\n", $filename);
                        close(FILE) || die "FATAL: Could not CLOSE '$output_file' $!";

                        # Bail when we get the first match
                        last;
                }
        }
        close(INCOMING) || die "FATAL: Could not close '$filename' $!";
}

答案 2 :(得分:0)

它应该匹配,除非$ _包含不同情况下的文本。

试试这个。

unless($_ =~ /Status\s+Code\s+1/i) {