从日志文件中删除控制/特殊字符

时间:2011-11-25 20:16:09

标签: bash sed tcl

我有一个tclsh捕获的日志文件,它捕获所有退格字符(ctrl-H,显示为“^ H”)和颜色设置序列(例如^ [[32m .... ^ [[0m] )。删除它们的有效方法是什么?

^ [...米

这一个很容易,因为我可以做“sed -i /^ [。* m / g”来删除它们

1 H

现在我有“sed -i s /.^ H //”,它“应用”一个退格,但我必须保持循环,直到没有更多的退格。

while [ logfile == `grep -l ^H logfile` ]; do sed -i s/.^H// logfile ; done;

“sed -i s /.^ H // g”不起作用,因为它会匹配连续的退格。对于我的日志文件,此过程需要11分钟,大约6k行,这太长了。

有什么更好的方法可以删除退格键吗?

4 个答案:

答案 0 :(得分:2)

您总是可以编写一个简单的管道命令来实现退格剥离,如下所示:

#include <stdio.h>
#include <stdlib.h>

#define BUFFERSIZE 10240

int main(int argc, char* argv[])
{
    int c ;
    int buf[BUFFERSIZE] ;
    int pos = 0 ;
    while((c = getchar()) != EOF)
    {
        switch (c)
        {
        case '\b':
        {
            if (pos > 0)
                pos-- ;
            break ;
        }
        case '\n':
        {
            int i ;
            for (i = 0; i < pos; ++i)
                putchar(buf[i]) ;
            putchar('\n') ;
            pos = 0 ;
            break ;
        }
        default:
        {
            buf[pos++] = c ;
            break ;
        }
        }
    }
    return 0 ;
} 

我只给了代码一个最小的测试,你可能需要调整缓冲区sze,具体取决于你的行数。断言pos是&lt;可能是一个想法。 pos ++之后的BUFERSSIZE只是为了安全!

或者你可以用Tcl代码实现类似的东西,它首先捕获日志文件;但不知道它是如何运作的,这有点难以说。

答案 1 :(得分:1)

你可以尝试:

sed -i s/[^^H]^H//g

这可能会或者可能不会一气呵成,但至少应该比你现在做的那样快一个。

答案 2 :(得分:0)

你知道“sed”不只是做换人吗? sed脚本的命令必须在不同的行上(或者至少它们在我在这台机器上的sed版本上)。

sed -i bak 's/^[[^^]]*m//g
: again
s/[^^H]^H//g
t again' logfile

:设置标签(在这种情况下为again),t分支到标签(如果已执行任何替换)(自开始/最后一个分支以来)。将那些围绕适当的s的圈子包裹起来,直到它不再适用为止。

答案 3 :(得分:0)

只是把它放在这里,我最终做到了这一点。这不是一个漂亮的解决方案,不像杰克逊的答案那样灵活,但在我的特定情况下做了我需要的。我基本上使用内部循环为sed生成匹配字符串。

# "Applies" up to 10 consecutive backspaces
for i in {10..1}; do
  match=""
  for j in `seq 1 $i`; do
    match=".${match}^H"
  done;

  # Can't put quotes around s//g or else backspaces are evaluated
  sed -i s/${match}//g ${file-to-process}
done;