Perl:如何解析文件并打印与用户输入的字符串匹配的每一行?

时间:2017-10-11 00:56:26

标签: regex perl

我是编程新手所以请耐心等待。我正在研究一个Perl脚本,询问用户他们想要搜索的不同项目的数量以及这些项目是什么,按ENTER键将它们分开。那部分工作正常。

然后,脚本将打开一个文件,解析并打印与用户最初列出的项匹配的每一行。这是我尚未弄清楚的部分。我尝试了不同的代码变体。我看到很多人建议使用索引功能,但我没有运气。当我为 $ line =〜/ TEXT / 交换 $ line =〜$ array 时,似乎确实有效。我希望这里有人能说清楚。

提前致谢!

#!usr/bin/perl
use strict;
use warnings;

my $line;
my $array;

print "Enter number of items: ";        
chomp(my $n = <STDIN>);

my @arrays;                                                     
print "Enter items, press enter to separate: \n";
for (1..$n) {
    my $input = <STDIN>;
    push @arrays, $input;
}

open (FILE, "file.txt") || die "can't open file!";      
chomp(my @lines = <FILE>);
close (FILE); 

foreach $array (@arrays) {                                      
        foreach $line (@lines) {
            if ($line =~ $array) {
                print $line, "\n";
        }
    }
}

2 个答案:

答案 0 :(得分:0)

@purplekushbear欢迎来到Perl!在Perl中,有不止一种方法可以做到这一点(TIMTOWTDI)所以请本着教学的精神来理解它。 首先是你的第一行 - #! (sha bang line)缺少perl的前导/路径。在Linux / UNIX环境中,如果您的脚本可执行#!之后的路径!用于运行您的程序。 ---如果你在/ usr / bin / perl上做一个ls你应该看到它。有时它位于/ bin / perl或/ usr / local / bin / perl。 当这个人提到你忘了唠叨他们指的是你在哪里设置$ input变量。就像你为$ n做的那样扼杀,你会没事的。 至于程序的主要部分,请返回并阅读您想要做的事情,并做到可能更简单的事情。我认为你在这个问题上有一个良好的开端,似乎知道数组以@开头,标量变量使用$ sigil,你使用strict是很好的。 这是解决问题的一种方法:

#!/usr/bin/perl
use strict;
use warnings;

print "Enter number of items: ";
chomp(my $num = <STDIN>);

my @items = ();
print "Enter items, press enter to separate: \n";
for (1 .. $num)
{
    chomp(my $input = <STDIN>);
    push @items, $input;
}
open (FILE, "file.txt") || die "can't open file because $!";
while (my $line = <FILE>)
{
    foreach my $item (@items)
    {
        if ($line =~ m/$item/)
        {
            print $line;
            last;
        }
    }
}
close (FILE);

注意我使用名称@items代替@arrays,这将使您在某天回到它时更容易理解代码。始终着眼于可维护性。无论如何,问你是否有任何问题,但由于我留下了大部分代码,我认为你不会有太多麻烦搞清楚。 Perldoc和谷歌是你的朋友。例如。你可以输入:

perldoc -f last 

了解最后的工作方式。玩得开心!

答案 1 :(得分:0)

在你的脚本中你忘了在给用户输入的同时添加chomp,然后你需要在匹配模式时持续内部循环。

然后这是另一种方式,您可以使用不同的方法尝试以下相同的事情。

我正在使用变量名$regex而不是@array。在$regex变量中,我将用户输入值与|连接起来。 (在正则表达式|中表现得像or)。连接时我正在使quotemeta逃脱特殊字符。然后,我为$regex变量

制作了qr预编译的正则表达式
#!usr/bin/perl
use strict;
use warnings;

print "Enter number of items: ";        
chomp(my $n = <STDIN>);

my $regex;
print "Enter items, press enter to separate: \n";

for (1..$n) 
{
    chomp(my $input = <STDIN>);
    $regex .= quotemeta($input)."|";
}

chop $regex; #remove the last pipe
$regex = qr($regex);

open my $fh,"<", "file.txt" || die "can't open file!";      

while(<$fh>)
{
    print if(/$regex/i);
}

然后用户@ikegami说出他的评论,你可以使用Perl内置的@ARGV方法代替STDIN,例如

你的方法

my @array = @ARGV;

另一种方法

my $regex = join "|", map { quotemeta $_ } @ARGV; 

然后运行脚本perl test.pl input1 input2 input3

始终使用3个参数来打开文件