我有一个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行,这太长了。
有什么更好的方法可以删除退格键吗?
答案 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;