2011-04-08 58 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的命令僅僅是一個更好的可讀性,和第一線留作練習。 :)