日志文件包含许多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
答案 0 :(得分:1)
如果我正确理解了Python日志文件的结构,则以下是一个很小的sed
解决方案,它的神秘性比看上去要低
#!/usr/bin/sed -f
/^Traceback/{
:here
N
/\nKevinCustomError/b
s/.*\n\(Traceback\)/\1/
b here
}
总结,该脚本仅对以Traceback
开头的行执行操作;在这些行上,脚本会继续添加新行(N
),并随后检查新添加的行是否以KevinCustomError
开始;如果是这种情况,脚本将分支到最后并打印多行图案空间;如果不是,那么脚本将从模式空间中除去最后一行Traceback
以外的所有内容,然后分支回到:here
并追加另一行(N
),依此类推。 / p>
详细信息如下:
#!/usr/bin/sed -f
:这是shebang行,它告诉Shell使用/usr/bin/sed
作为解释器,并通过-f
选项将file参数传递给它(这允许执行./script file
而不是sed -f script file
); /^Traceback/
仅匹配以Traceback
开头的行; {…}
将仅对那些在步骤2中匹配的行执行的命令进行分组;
:here
不是命令,而只是一个标签,它通过t
est或b
ranch命令标记了我们可以返回的行; N
读取并在当前模式空间后面添加以下文本行,并在其之间插入换行符\n
,从而使模式空间成为多行; /\nKevinCustomError/b
,如果模式空间包含b
后跟KevinCustomError
,则此\n
到脚本末尾;
p
删除多行图案空间,该空间以Traceback
开头,其中包含(至少)一个\n
,并且包含{ {1}}(最后一个)KevinCustomError
之后; \n
(如果3.中的模式不匹配,我们就在这里)删除模式空间的前导部分,直到最后一个s/.*\n\(Traceback\)/\1/
;包括最后一个\n
; b here
分支到:here
,并且此时没有打印。答案 1 :(得分:0)
这是我试图鞭打的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”令牌(如果您愿意,可以替换它),然后在中间打印所有行(按照正确的顺序)。
答案 2 :(得分: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
答案 3 :(得分:0)
以下是awk
的另一种方式:
awk '
/^KevinCustomError/ { for(;x<length(arry);) print arry[++x]; print $0 }
/^Traceback/ { delete arry; i=x=0 }
{ arry[++i]=$0 }
' logFile