从正则表达式中仅提取单个组

从正则表达式中仅提取单个组

我正在尝试使用 zgrep 从一些被黑客攻击在一起的日志文件中获取数字列表。所以,我正在使用:

zgrep -ie "total time: .* ms" *

这将返回我关心的整行。我只想要号码。 (在总时间之后但在“ms”之前)有什么方法可以获取此信息而无需进一步处理?

答案1

如果您grep是 GNUgrep并且假设您要查找的数字是该行中的唯一数字:

zgrep -ioEe '[0-9]+(\.[0-9]+)?' *

如果没有,您可以随时过滤zgrep的输出:

zgrep -ie 'total time: .* ms' * | sed 's/.*total time: \(.*\) ms.*/\1/'

答案2

使用 GNU grep,您可以结合两个功能来获得您想要的:

  • -o仅打印该行的匹配部分的选项;
  • Perl 正则表达式及其零宽度环视断言限制比赛前后可能出现的内容。
zgrep -Pi -o '(?<=total time: )([0-9.]+)(?= *ms)' *

或者,您也可以调用 Perl。

perl -MPerlIO::gzip -e 'for (@ARGV) {
    open IN, (/\.gz$/ ? "<:gzip" : "<"), $_ or die "$_: $!";
    $name = $_;
    while (<IN>) {
        if (/total time: ([0-9.]+) *ms/i) {print "$name:$1\n"}
    }
    close IN
}' *

如果没有这些工具,您可以手动迭代文件并调用sed以删除除您感兴趣的内容之外的所有内容。

for x in *; do
  case "$x" in
    *.gz) <"$x" gunzip;;
    *) cat "$x";;
  esac | sed -n -e 's/^.*total time: \([0-9.]*\) *ms.*$/\1/p'
done

相关内容