8

一个日志文件包含许多 Python 回溯。我只关心由于KevinCustomError. 文件中可能存在不止一个此类错误。

我如何使用grep另一个流行的 unix 命令或它们的组合来为我的特定错误转储整个回溯?

这是一个示例日志文件。我想要这个文件的第 1-3 行。在真实的日志文件中,回溯要长得多。

Traceback (most recent call last):
  File "<stdin>", line 1, in ?
KevinCustomError: integer division or modulo by zero
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ZeroDivisionError: integer division or modulo by zero
4

4 回答 4

2

这是我尝试一起编写的 AWK 脚本。

awk '{a[NR]=$0}; /KevinCustomError/ {for(i=0; a[NR-i] !~ /Traceback/; i++) {} i++; while(i-- >= 0) {print a[NR-i]}}' logfile

或者,以文件形式。

{a[NR] = $0};

{
    if ($0 ~ /KevinCustomError/)
    {
        for (i = 0; a[NR-i] !~ /Traceback/; i++)
        {}
        i++
        while (i-- >= 0)
        {
            print a[NR-i];
        }
    }
}

像这样使用:awk -f logscript.awk logfile

对AWK不太熟悉,欢迎批评。基本上,它会跟踪到目前为止读取的所有行,并且只是向后搜索以找到“Traceback”标记(如果您愿意,可以替换它),然后打印中间的所有内容(以正确的顺序)。

于 2013-07-09T23:19:48.673 回答
1

如果我正确理解了 Python 日志文件的结构,以下是一个小sed解决方案,它不像看起来那么神秘

#!/usr/bin/sed -f
/^Traceback/{
:here
N
/\nKevinCustomError/b
s/.*\n\(Traceback\)/\1/
b here
}

总之Traceback,脚本只对以;开头的行执行操作。在这些行上,脚本不断添加一个新行 ( N) 并随后检查新添加的行是否以KevinCustomError;开头 如果是这种情况,则脚本分支到末尾并打印多行模式空间;如果不是,则脚本从模式空间中删除除最后Traceback一行之外的所有内容,然后分支返回:here并附加另一行 ( N),依此类推。

详细地说,它的工作原理如下:

  1. #!/usr/bin/sed -f:这是shebang行,它告诉 shell/usr/bin/sed用作解释器,并通过-f选项将文件参数传递给它(这允许执行./script file而不是sed -f script file);
  2. /^Traceback/仅匹配以Traceback;开头的行
  3. {…}将仅对在第 2 步匹配的行执行的命令分组;
    1. :here不是一个命令,而只是一个标签,它标记了我们可以通过test 或branch 命令返回的行;
    2. N读取并附加当前模式空间的下一行文本,并在其间插入换行符\n,这使得模式空间成为多行;
    3. /\nKevinCustomError/b,如果模式空间包含前面有一个; 这b将延伸到脚本的末尾KevinCustomError\n
      • 这会导致p多行模式空间 rinting,它以 开头Traceback,其中包含(至少) a \n,并且KevinCustomError在 (last) 之后包含\n;
    4. s/.*\n\(Traceback\)/\1/(如果 3. 中的模式不匹配,我们就在这里)删除模式空间的前导部分,直到并包括最后一个\n
    5. b here分支到:here,此时不进行打印。
于 2020-01-30T23:24:11.103 回答
0

这是另一种方式awk

awk '
/^KevinCustomError/ { for(;x<length(arry);) print arry[++x]; print $0 } 
/^Traceback/        { delete arry; i=x=0 }
                    { arry[++i]=$0 }
' logFile
于 2013-07-10T00:37:03.380 回答
0

我以前用过类似的东西来解决类似的问题。作为奖励,如果您多次出现 KevinCustomError,它将提取每个的回溯。

#!/bin/bash

INPUT=$1
TOP='Traceback'
BOTTOM='KevinCustomError'

grep -n "$BOTTOM" $INPUT | while read match
do
    # This gets just the line number from the grep command
    END=${match%%:*}
    # Gets just the part of the file before END, flips it,
    # then gets the line number for TOP
    TEMP=`head -n $END $INPUT | tac | grep -n $TOP`
    # TEMP is really the number of lines from END to Traceback
    START=`expr $END - ${TEMP%%:*} + 1`
    echo $START $END
    sed -n "$START, $END p" < $INPUT
done

在跟踪翻转的测试数据上运行时的输出(因为它更有趣):

4 6
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
KevinCustomError: integer division or modulo by zero
于 2013-07-09T23:30:51.983 回答