如何使用perl搜索同一行中的多个字符串?

如何使用perl搜索同一行中的多个字符串?,perl,Perl,我知道如何通过在perl脚本中搜索文件中的单个字符串来提取一行,下面的命令工作得非常好,它给出了包含255.255.255.255的行 my @newList = grep /255.255.255.255/, @File1; 但是,当我想在一个文件中搜索多个字符串(字段)时,grep命令不起作用 我在下面有一个文件,如果sourceipaddress、destipaddr和端口号匹配,它应该提取整行并写入一个数组 gitFile: 访问abc允许tcp源IP地址源子网目的地PADDR目的子网

我知道如何通过在perl脚本中搜索文件中的单个字符串来提取一行,下面的命令工作得非常好,它给出了包含255.255.255.255的行

my @newList = grep /255.255.255.255/, @File1;
但是,当我想在一个文件中搜索多个字符串(字段)时,grep命令不起作用

我在下面有一个文件,如果sourceipaddress、destipaddr和端口号匹配,它应该提取整行并写入一个数组

gitFile:

访问abc允许tcp源IP地址源子网目的地PADDR目的子网eq端口号

这就是我选择的解决问题的方法,我根据字段进行拆分,并使用grep在数组中搜索这些字段,但它似乎不起作用(尝试了5种不同的方法,下面对此进行了注释,但没有任何命令起作用)。我只想要一种在一行中搜索多个字符串(包括ipaddress)的方法。由于我是perl新手,所以我正在努力解决这个问题,请提供帮助

my @columns = split(' ',$line);
    my $fld0 = $columns[3];
    my $fld3 = $columns[6];
    my $fld5 = $columns[9];

    #my @gitLines = grep {$_ =~ "$fld0" && $_ =~ "$sIP" && $_ =~ "$dIP" && $_ =~ "$fld5"} @gitFile;

  #my @gitLines = @gitFile =~ /$fld0|$sIP|$dIP|$fld5/;

   #my @gitLines = grep /$fld0/ && /$sIP/ && /$dIP/ &&/$fld5/,@gitFile;

   #grep {$fld0} && {$sIP} && {$dIP} && {$fld5} @gitFile;

  #my @gitLines = grep /255.255.255.255/ && /$fld0/, @File1;

我正在Linux GNU/Linux flavor中尝试这一点,没有完整的代码,不清楚您的程序中发生了什么。我根据上下文推断,
$line
有一个行模板,因此可以从中提取模式,
@gitFile
有一个文件中的所有行。然后,在这些行中,您要确定具有所有三种模式的行

  • 第一次尝试应该写为

    my @gitLines = grep { /$fld0/ && /$fld1/ && /$fld2/ } @gitFile;
    
    虽然您确实可以选择您的分隔符,但对于除
    /
    之外的任何分隔符,必须有
    m
    ,因此您可以使用
    grep{m“$fld0”&&&&·}
    (explicit
    $\uuu
    中没有值,因为它只会增加噪声)。但我发现在这种情况下使用不常见的分隔符是很模糊的

  • 第二次尝试是错误的,因为您无法匹配数组。此外,即使只有一个模式匹配,使用交替
    |
    也会匹配

  • 另一种方法是形成一个正则表达式来解析行,而不是在每个字段上单独匹配

    my $re = join '.*?', map { quotemeta } (split ' ', $line)[3,6,9];
    my @gitLines = grep { /$re/ } @gitFile;
    
    正则表达式模式应该使用但是对于简单的
    *?
    模式,字符串可以工作

    与上面的
    grep
    不同,这里的模式需要以精确的顺序出现在一行中。一个明显的优点是它在行上运行regex一次,而在
    grep
    中,引擎启动三次

请注意,通常最好逐行处理文件,除非有特定原因需要提前读取整个文件。比如说

# $line contains patterns that must all match at indices 3,6,9
my $re = join '.*?', map { quotemeta } (split ' ', $line)[3,6,9];

my @gitLines;
open my $fh, '<', $git_file_name  or die "Can't open $git_file_name: $!"; 
while (<$fh>) {
    next if not /$re/;
    push @gitLines, $_;
}
#$line包含的模式必须在索引3,6,9处全部匹配
my$re=join'.*?',map{quotemeta}(split'',$line)[3,6,9];
我的@gitLines;

打开我的$fh,“基本上,我相信您正在尝试在一行中查找多个匹配项,并且您已经在一个名为
@gitFile
的数组中找到了每一行

根据我的理解,我正试图用一种更简单的方式来做这件事

$fld0 = 'pattern1';
$fld1 = 'pattern2';

foreach(@gitFile)
{
     if(($_=~ m/$fld0/ && $_ =~ m/$fld1/))  
     { 
         push(@gitLines ,$_);
     }
}

@gitFile
中有什么?一个文件的所有行?如果我理解,你想提取文件中的所有IP吗?对吗?我们可以举一个输入的例子吗?访问列表防火墙1允许tcp 10.100.38.224 255.255.255.240 10.185.34.240 255.255.255.255.240 eq 9012…这就是内容的样子。我想根据第3、第4、第6和第9个字段进行搜索,并提取具有此组合的行。请:编辑带有澄清的问题。很多事情还不清楚。(顺便说一句,您的示例显示了第三、第六和第九个字段——没有您在注释中提到的第四个字段?)为了回答这个问题,我们需要一些示例数据和所需的输出。如果没有这些,我们无法猜测到底发生了什么。请把你的问题包括在内。