LinuxShell:将Perl代码更改为LinuxShell,grep逐行

LinuxShell:将Perl代码更改为LinuxShell,grep逐行,perl,shell,grep,Perl,Shell,Grep,下面的代码是Perl脚本,grep行带有hostlog中的“Stage”。然后逐行将内容与正则表达式匹配,如果找到,则按1添加计数: $command = 'grep \'Stage \' '. $hostlog; @stage_info = qx($command); foreach (@stage_info) { if ( /Stage\s(\d+)\s(.*)/ ) { $stage_number = $stage_number+1; } } 那么如何在l

下面的代码是Perl脚本,grep行带有hostlog中的“Stage”。然后逐行将内容与正则表达式匹配,如果找到,则按1添加计数:

$command = 'grep \'Stage \' '. $hostlog;
@stage_info = qx($command);
foreach (@stage_info) {
    if ( /Stage\s(\d+)\s(.*)/ ) {
        $stage_number = $stage_number+1;
    }
}

那么如何在linux shell中实现这一点呢?根据我的测试,我们不能一行一行地循环,因为里面有空间

差不多了。bash没有多个数字的表达式

#!/bin/bash 

command=( grep 'Stage ' "$hostlog" )

while read line 
do
  [ "$line" != "${line/Stage [0-9]/}" ] && (( ++stage_number ))
done < <( "${command[@]}" )
还是这个

stage_number=` grep -c 'Stage \d\+\s' "$hostlog" `

如果在最初的perl中,stage_number未初始化,或者初始化为0。

如果我正确理解了这个问题,您应该能够在shell中很好地完成这项工作:

while read; do
    if echo ${REPLY} | grep -q -P "'Stage' "; then
        # Do what you need to do
    fi
done < test.log
读取时
;做
如果echo${REPLY}| grep-q-P“'Stage';然后
#做你需要做的事
fi
完成

请注意,如果您的grep命令支持-p选项,那么您可以像第二次测试一样使用Perl正则表达式。

这是一段可怕的Perl代码。原因如下:

  • 看起来您没有使用
    use strict;使用警告。这是一个巨大的错误,不会阻止错误的发生,只会掩盖错误
  • 使用
    qx()
    从文件中grep行是一件完全多余的事情,因为这是Perl最擅长的事情。“炮轰”这样的过程通常会减慢程序的速度
  • 使用一些空格使代码可读。这很难理解,而且看起来比实际情况更复杂
  • 通过在正则表达式中使用括号捕获字符串,但从不使用这些字符串
  • 回复:
    $stage\u number=$stage\u number+1
    ,参见第3点。此外,还可以编写
    $stage\u number++
    。使用
    ++
    操作符将使代码更清晰,防止出现未初始化的警告,并为您节省一些输入
  • 以下是您的代码的外观:

    use strict;
    use warnings;
    
    open my $fh, "<", $hostlog or die "Cannot open $hostlog for reading: $!";
    while (<$fh>) {
        if (/Stage\s\d+/) {
            $stage_number++;
        }
    }
    
    使用严格;
    使用警告;
    
    打开我的$fh,“你不能用内部捕获做任何事情,为什么要麻烦呢?你可以用
    grep
    做任何事情:

    $ stage_number=$(grep -E 'Stage\s\d+\s' | wc -l)
    
    这是使用扩展正则表达式。我相信GNU版本在没有
    -E
    参数的情况下使用这些表达式,并且在Solaris中,即使是
    egrep
    命令也可能不太允许使用此正则表达式


    如果您还有其他事情要做,您必须在问题中解释。

    En.好的。在Perl中,我们可以得到匹配的部分$1和$2。因此,除了数字之外,如何在linux shell中获得这些值?谢谢!如果您需要匹配部分的详细信息,您必须使用sed重新格式化文件。或者,您可以使用shell表达式来SSA将这行代码组装到您需要的部分。要求代码翻译显然与SO无关。发布您的shell代码,人们肯定会愿意帮助您解决特定的问题,但他们不会为您编写。谢谢,这几乎是我所需要的。但似乎有一些语法错误。好的,我已经实际测试了这些代码现在的版本应该适合你了。别忘了将hostlog设置为$hostlog,或者用合适的文件名回复$hostlog。幸运的是,他使用的是linux,所以,GNU grep。
    grep-E
    egrep
    相同
    grep-c
    将直接返回一个计数,而不需要
    wc-l
    哦,我忘了
    -c
    pa参数。这是所有版本的
    grep
    中的标准。虽然这些成分是有效的批评,但这并不能回答提出的问题。此外,错误的正则表达式。不,它不是“错误的”“。正如我所解释的,捕获任何内容都没有意义,因此不需要括号,因此不需要添加与空白和任何内容匹配的
    \s.*
    部分。此外,是的,它确实回答了这个问题,在更大的方面,它是可以实际使用并因此翻译的Perl代码。这里更大的答案是使用shell脚本没有任何好处。
    $ stage_number=$(grep -E 'Stage\s\d+\s' | wc -l)