如何排除 SED 范围中的最后一行

问题描述 投票:0回答:5

我的日志文件包含多行单个日志输出,如下所示:

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

我必须从 TRACE 输出中清除它。

我用

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

...然后得到

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

Sed 删除包含范围,并且不在 TRACE 块之后打印 DEBUG 和 ERROR 行。 我用 sed 尝试了其他方法,但没有找到如何仅删除 TRACE 块。

Sed 非常好,但也许我应该使用另一个 Unix 实用程序...请建议。

sed
5个回答
2
投票

这里有一种方法可以在 sed 中完成您想要的操作,尽管这是我通常使用 perl 的情况。这使用 sed 的“保留空间”来收集日志文件的每个部分,并在看到下一部分的开始时打印(或不打印)整个部分。

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

但是,回答问题的主题,我认为不可能从范围中排除最后一行。


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

AWK 来救援;-)(注意:它可以粘贴到一行。)


0
投票

这提供了一种将输入拆分到不同位置的合理技术。 使用案例会很好,但如果您坚持将字符串锚定在行的开头,我认为这是不可能的。

#!/bin/sh

执行3>&1
执行4> /dev/null
执行5>&1
同时读取 -r 行;做
回显 $line | grep ^DEBUG >&3 && 执行 >&3 && 继续
回显 $line | grep ^TRACE >&4 && 执行 >&4 && 继续
回显 $line | grep ^错误 >&5 && 执行 >&5 && 继续
回显$行
完毕


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 命令只是为了更好的可读性,第一行留作练习。 :)


0
投票

这是一个将 sed 的保留空间用作布尔值的解决方案:当且仅当保留空间为空时,才会输出当前行。

sed -e '/^TRACE/ h ; /^\(DEBUG\|ERROR\)/ { x ; s/.*// ; x } ; x ; /./ { x ; d } ; x'

其工作原理如下:

  • 如果当前行与
    ^TRACE
    匹配,则将其放入保留空间,以便禁用输出(见下文)。
  • 如果当前行与
    ^\(DEBUG\|ERROR\)
    匹配,则清除保留空间,以便启用输出(见下文)。
  • 当且仅当保留空间包含某些内容时,
    x ; /./ { x ; d } ; x
    才会删除当前模式空间。由于没有使用
    -n
    ,如果模式空间没有被删除,就会输出。根据需要,保留空间被保留(对于块的其他行):正好执行 2 个
    x
    (因为
    d
    开始一个新的循环)。

备注:

  • 即使第一行与
    ^\(TRACE\|DEBUG\|ERROR\)
    不匹配,此解决方案也有效(仅删除
    TRACE
    块)。
  • 图案空间或保持空间中不会累积线条。因此,该解决方案具有内存高效性,并且避免了 POSIX 允许的潜在限制:“模式和保存空间均应能够保存至少 8192 字节。” (具有大行的文本文件可能仍会受到限制的影响,但无论如何在这种情况下 sed 都无能为力。)
© www.soinside.com 2019 - 2024. All rights reserved.