用于解析文本文件并匹配字符串的Perl脚本

用于解析文本文件并匹配字符串的Perl脚本,perl,Perl,我正在编辑我的问题以添加更多细节 脚本执行命令并将输出重定向到文本文件 然后脚本解析文本文件以匹配以下字符串“Standard 1.1.1.1” 文本文件中的输出为: Host Configuration ------------------ Profile Hostname -------- ---------

我正在编辑我的问题以添加更多细节

脚本执行命令并将输出重定向到文本文件

然后脚本解析文本文件以匹配以下字符串“Standard 1.1.1.1”

文本文件中的输出为:

             Host Configuration
             ------------------

             Profile              Hostname
             --------             ---------

             standard             1.1.1.1
             standard             1.1.1.2
如果我搜索1.1.1.1或standard,则代码可以工作。当我一起搜索标准1.1.1.1时,下面的脚本失败

这就是我在testtest.pl上得到的错误“找不到字符串:standard 172.25.44.241”

#!/usr/bin/perl
use Net::SSH::Expect;     
use strict;
use warnings;
use autodie;

open (HOSTRULES, ">hostrules.txt") || die "could not open output file";
my $hos = $ssh->exec(" I typed the command here  ");
print HOSTRULES ($hos);
close(HOSTRULES);

sub find_string
{
my ($file, $string) = @_;
open my $fh, '<', $file;
while (<$fh>) {
    return 1 if /\Q$string/;
}
die "Unable to find string: $string";
}

find_string('hostrules.txt', 'standard 1.1.1.1');
!/usr/bin/perl
使用Net::SSH::Expect;
严格使用;
使用警告;
使用自动模具;
打开(HOSTRULES,“>HOSTRULES.txt”)| | die“无法打开输出文件”;
my$hos=$ssh->exec(“我在这里键入了命令”);
印刷版(居屋);;
关闭(主机规则);
子查找字符串
{
我的($file,$string)=@;

打开我的$fh,“也许写一个函数:

use strict;
use warnings;
use autodie;

sub find_string {
    my ($file, $string) = @_;
    open my $fh, '<', $file;
    while (<$fh>) {
        return 1 if /\Q$string/;
    }
    die "Unable to find string: $string";
}

find_string('output.txt', 'object-cache enabled');
find_string('hostrules.txt', 'standard\s+1.1.1.1'); # note '\s+' here
使用严格;
使用警告;
使用自动模具;
子查找字符串{
我的($file,$string)=@;
打开我的$fh,'

程序只会扫描文件,直到它看到缓存被禁用的指示,并会在该点异常退出。

您正在扫描文件以查找特定字符串。如果该字符串未在该文件中找到,则希望抛出错误。听起来像是一个作业


这将使用常量
required\u字符串定义为带引号的regexp。

首先,为什么要使用
Net::SSH::Expect
?是否执行远程命令?如果不是,则只需执行程序并等待其完成即可

其次,失败的似乎是正则表达式。您正在搜索文本表达式
standard 1.1.1.1
,但在示例文本中,所需字符串似乎包含制表符或多个空格,而不是单个空格。请尝试将调用更改为
find_string
函数:

use strict;
use warnings;
use autodie;

sub find_string {
    my ($file, $string) = @_;
    open my $fh, '<', $file;
    while (<$fh>) {
        return 1 if /\Q$string/;
    }
    die "Unable to find string: $string";
}

find_string('output.txt', 'object-cache enabled');
find_string('hostrules.txt', 'standard\s+1.1.1.1'); # note '\s+' here

我已经在上面发布了我的代码。我正在使用您提供的函数。当我将函数与我的代码集成时,脚本失败。对于您提供的函数,我如何测试否定大小写。我的意思是我想检查文本文件中是否不存在字符串。例如,我想检查字符串“文件输出中不存在“object cache enabled”(启用对象缓存)。TXT请定义“Tworn and error”(抛出和错误)当找不到它时,您希望发生什么?我已在下面添加了更新的脚本。该脚本抛出以下错误。““Name”main::OUTPUTFILE“仅使用一次:sm.pl第19行可能存在键入错误。找不到字符串:sm.pl第27行的对象缓存。”您正在使用一把别致的电动螺丝刀将钉子钉在一块板上。
input\u record\u separator
不用于匹配。1)学究式地说,“只使用一次”消息是一个警告,而不是一个错误。2)您的示例中没有27行代码。我共有11行。@len Jaffe,我已经为问题添加了更多详细信息。请您看一下,并告诉我需要做什么?有什么理由将整个文件存储在内存中吗?没有理由,除了它允许我使用
grep
并保留pr之外gram很简单。否则,我会在读取每一行时进行循环。如果输出文件不是太大(比方说少于100000行),slurp文件应该可以。我只是测试了一下
grep
是否与文件句柄一起工作。没有。在我的答案中添加了不使用
grep
并将整个文件slurp。是的,第二个示例包含一个小错误(第一个示例的遗留问题)。我认为第二个答案是正确的方法(我在回答中使用了相同的想法。)我正在使用Net::SSH::Expect,因为我需要登录到cisco路由器来执行命令。而且“\s+”不起作用。我试过了。还有其他建议吗?如何解析文本文件并检查字符串是否不存在?第一个示例是“如果找不到X,则失败”;第二个示例是“如果我发现了我不想要的东西就失败”。
use strict;
use warnings;
use features qw(say);
use autodie;

use constant {
    OUTPUT_FILE   => 'output.txt',
    NEEDED_STRING => "object-cache enabled",
};

open my $out_fh, "<", OUTPUT_FILE;
my @output_lines = <$out_fh>;
close $out_fh;
chomp @output_lines;

grep { /@{[NEEDED_STRING]}/ } @output_lines  or
    die qq(ERROR! ERROR! ERROR!);    #Or whatever you want
use strict;
use warnings;
use features qw(say);
use autodie;

use constant {
    OUTPUT_FILE   => 'output.txt',
    NEEDED_STRING => qr(object-cache enabled),
};

open my $out_fh, "<", OUTPUT_FILE;
my $output_string_found;   # Flag to see if output string is found

while ( my $line = <$out_fh> ) {
    if ( $line =~ NEEDED_STRING ){
        $output_string_found = "Yup!"
        last;   # We found the string. No more looping.
    }
}
die qq(ERROR, ERROR, ERROR) unless $output_string_found;
system("cmd > file.txt") or die "Couldn't execute: $!";
find_string('hostrules.txt', 'standard\s+1.1.1.1'); # note '\s+' here