在Perl中使用awk来解析两个字符串之间的所有内容

时间:2013-04-26 08:50:33

标签: perl ssh awk split capture

我在HP-UX服务器上不断更新大量日志文件。我创建了Perl代码,以找出我正在使用的字符串所在的日志文件的名称。 Perl使用split获取文件名并将其传递给变量。使用userinput我将start和stop字符串创建为两个变量。例如:

my $ssh = Net::OpenSSH->new($host, user => $user,
        master_opts => [ -o => 'NumberOfPasswordPrompts=1',
                         -o => 'PreferredAuthentications=keyboard-interactive,password'],
login_handler => \&login_handler);

$ssh-> error and die "Unable to connect" . $ssh->error;
my $output=$ssh->capture("grep .$userinput1. /app/bea/user_projects/domains/granite/om_ni.log*");

my $array = (split ":", $output)[0];
print "$array"."\n";

[编辑]:正如你们所要求的,上面是$数组填充方式的开始。下面是awk序列开始的地方:

my $a= "INFO - $userinput1";print $a;
my $b= "INFO - ProcessNode terminated... [$userinput1]";print $b;

使用awk作为ssh capture命令的一部分,它将搜索整个日志文件并捕获字符串$ a和string $ b之间的每一行,然后将所有内容放在另一个数组中。例如:

my $output2=$ssh->capture("awk -v i=$array '$a,$b' i");

这里$ array是日志文件的完整路径所在的位置,它作为传递变量完全正常工作。 我尝试使用不带-v参数的awk,根本不重要。

[编辑2]:这是打印“$ array”的结果。“\ n”;

/app/bea/user_projects/domains/granite/om_ni.log.2

当我运行perl脚本时,我得到了结果:

INFO - 28B26AD1-E959-4F5F-BD89-A7A6E601BE18INFO - ProcessNode terminated... [28B26AD1-E959-4F5F-BD89-A7A6E601BE18] syntax error The source line is 1.
The error context is
INFO - 28B26AD1-E959-4F5F-BD89-A7A6E601BE18,INFO - ProcessNode >>>  terminated. <<< ..  [28B26AD1-E959-4F5F-BD89-A7A6E601BE18]
awk: Quitting
The source line is 1. 

错误地以某种方式指向“终止”单词,但即使我在字符串中使用转义字符,它也不关心并返回相同的错误。

对此问题的任何帮助都非常感谢。非常感谢。

1 个答案:

答案 0 :(得分:0)

虽然我真的不知道awk,但是你调用它的方式似乎并不正确。 Here is the manual for awk on HP-UX

单引号($a,$b)中的部分应该是程序。但是,您传递了两个文本字符串,甚至没有引用它们来分隔它们。这不是一个有效的awk程序;因此语法错误。

我认为你想要的是类似'/$a/, /$b/'的程序(但同样,我不是awk专家)。

此外,您将文件名设置为变量i,然后在调用命令时使用i代替文件名。我不知道你为什么要这样做,我认为它甚至不会在文件名中使用变量。只需在文件名位置使用$array(为了清楚起见,您应将其重命名为$file)。

所以你的整个命令看起来应该是这样的:

"awk '/$a/,/$b/' $file"

在这个单一命令中,您正在处理三种不同的工具:Perl,SSH和awk。这很难调试,因为如果出现问题,很难说出问题出在哪里。为了得到这样的工作,你必须将任务分解成更小的部分。

在这种情况下,这意味着您应该手动SSH到服务器并使用awk,直到您获得正确的命令。只有当您确定自己拥有awk命令时,才应该尝试将其合并到Perl中。如果以这种方式分解任务会更容易。