【问题标题】:grep issue in PerlPerl 中的 grep 问题
【发布时间】:2018-08-02 10:31:07
【问题描述】:

以下来自 Perl 脚本..

$search2=  join(' ', $mo,$day,$hr); # Output "Aug 2 03"
$LOG1  = "/tmp/log"  # Log file path. It has $search2 inside it
$search1 = "issue|error"

这是我遇到问题的地方...

$failed = `"/bin/egrep" "$search1" "$LOG1"| grep "$search2"`;

没有grep "search2" 低于输出

Aug  1 01:03:40 something sudo: pam_unix(sudo:auth): authentication failure; logname=something uid=0 euid=0 tty=/dev/pts/1 ruser= something=  user=something
Aug  1 03:34:20 something  sudo: pam_unix(sudo:auth): authentication failure; logname=something uid=0 euid=0 tty=/dev/pts/0 ruser= something=  user=something
Aug  2 00:43:29 something sudo: pam_unix(sudo:auth): authentication failure; logname=something uid=0 euid=0 tty=/dev/pts/1 ruser= something=  user=something
Aug  2 03:02:33 someting  sudo: pam_unix(sudo:auth): authentication failure; logname=something uid=0 euid=0 tty=/dev/pts/1 ruser= something=  user=something

但是当使用| grep "$search2" 时没有得到任何东西

   print "$failed"; # It is not throwing any output of 'Aug 2 03'

但是,当我在 Linux 命令行上执行相同的操作时,我得到了所需的输出。下面我在linux命令行上使用

/bin/egrep "issue|error" "/tmp/log" | grep  "Aug 2 03"

请帮忙解决。

【问题讨论】:

  • 当 Perl 擅长此类任务时,为什么还要使用 grep?您确定您从 Perl 运行的命令与您在命令行上运行的命令相同吗?
  • 是的,我在 linux shell 中运行相同的命令,一个区别是我没有使用 ` ` 并且没有保存在变量中...
  • 我对 perl 很陌生,所以真的需要帮助...修复$failed = "/bin/egrep" "$search1" "$LOG1"| grep "$search2"; 这样我就可以使用 $failed 作为输出通过电子邮件发送。
  • 你试过简化吗?向我们展示最简单但不起作用的东西。
  • 当您的 grep 模式仅包含一个空格时,Aug 和数据中紧随其后的数字之间似乎有几个空格(或制表符?)。会不会是这个问题?

标签: regex shell perl


【解决方案1】:

我认为你应该听从达达在评论中给出的建议。如果您发布的内容真的是您所看到的,那么这是行不通的:

你像这样构建你的字符串:

$search2=  join(' ', $mo,$day,$hr);

这意味着您在月和日之间有一个空格。此外,您复制了未使用搜索字符串而获得的输出,如下所示:

Aug  1 01:03:40 something sudo: pam_unix(sudo:auth): authentication failure; logname=something uid=0 euid=0 tty=/dev/pts/1 ruser= something=  user=something

这显然不是 8 月到 1 日之间的一个空格。

我很确定,如果您使用十六进制编辑器查看文件 /tmp/log,您将不会在“Aug”和“1”之间看到一个空格。

您还可以从命令行调用命令并将其通过管道传送到 xxd,以查看十六进制内容。

【讨论】:

  • 让我重新检查一下。
  • @RishuA 您应该使用sprintf 来更好地控制格式。 $search2 = sprintf( '%s %2d %s', $mo, $day, $hr );
  • 不错!明白了。
【解决方案2】:

您无需为此调用 grep:

use autodie;
open my $fh, "<", $LOG1;
my $failed = "";
while (<$fh>) {
    $failed .= $_ if /$search1/o && /$search2/o;
}
close $fh;

【讨论】:

  • $search1 是一个正则表达式模式,所以/$search1/ 很好,但$search2 是文本,所以/$search2/ 应该是/\Q$search2/。 (这就是为什么 OP 使用egrep 作为第一个,grep 作为第二个。)
  • 是的,或者index($_, $search2) != -1。你的括号内的评论是有争议的。
  • 哦,你认为他们为什么没有同时使用grep
  • 我怀疑egrep 只是为了避免使用反斜杠。并在反引号内转义 perl 中的反斜杠。
  • 字面匹配的字符串不是正则表达式模式
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-07
相关资源
最近更新 更多