2011-04-08 55 views
0

有日志文件,其中包含这样的单日志输出多行:我如何排除最后一排SED范围

DEBUG : <line1>
<line2>
TRACE : <line11>
<line12>
<line13>
DEBUG : <line21>
<line22>
<line23>
TRACE : <line31>
<line32>
ERROR : <line41>
<line42>
TRACE : <line51>
<line52>
DEBUG : <line61>
<line62>

我不得不从跟踪输出清洁。

我用

sed -e "/^TRACE/,/^DEBUG\|^ERROR/d" <log.txt

...并获得

DEBUG : <line1>
<line2>
<line22>
<line23>
<line42>
<line62>

桑达删除包含性的范围,只是跟踪块后不打印调试和错误线。 我试着用sed的其他方式,但没有找到如何仅删除TRACE块。

Sed很不错,但也许我应该使用另一个Unix工具...请指教。

+0

向我们展示你想要的输出。感谢您使用格式! – shellter 2011-04-08 16:34:58

回答

0
awk '/^TRACE/ { 
       while ($0 !~ /^DEBUG/ || $0 !~ /^ERROR/) { 
        getline ; 
        if ($0 ~ /^DEBUG/ || $0 ~ /^ERROR/) { 
         print $0 ; 
         next 
        } 
       } 
       } 
    { print $0 }' FILENAME 

AWK救援;-)(注:可以粘贴到一个行)

0

这为拆分输入到不同的地方合理的技术。使用案例会很好,但如果你坚持把字符串固定在行首,我不相信这是可能的。

 
#!/bin/sh 

exec 3>&1 
exec 4> /dev/null 
exec 5>&1 
while read -r line; do 
echo $line | grep ^DEBUG >&3 && exec >&3 && continue 
echo $line | grep ^TRACE >&4 && exec >&4 && continue 
echo $line | grep ^ERROR >&5 && exec >&5 && continue 
echo $line 
done 

2

这是一种在sed中执行所需操作的方法,虽然这是我通常使用perl的情况。这使用sed的“保留空间”来收集日志文件的每个部分,并且一旦它看到下一部分的开始就打印(或不打印)整个部分。

sed -n -e '/^\(TRACE\|DEBUG\|ERROR\)/ ! { H ; $!b } ; x ; /^\(DEBUG\|ERROR\)/ p' 

然而,对问题的问题,我不认为这是可以从范围中排除的最后一行。

0

你可以复制你的标签,只删除了他们的第一个:

sed -E "s/^((DEBUG)|(ERROR)) : /\1 : \n\1 /" | \ 
sed "/^TRACE/,/^DEBUG\|^ERROR/d" | sed "s/^</\t</" 

DEBUG : 
DEBUG <line1> 
     <line2> 
DEBUG <line21> 
     <line22> 
     <line23> 
ERROR <line41> 
     <line42> 
DEBUG <line61> 
     <line62> 

最后sed的命令仅仅是一个更好的可读性,和第一线留作练习。 :)