Bash - 将输出重定向到文件时处理退格控制字符

时间:2015-12-15 06:06:18

标签: linux bash shell

我必须在后台运行第三方程序并将其输出捕获到文件。我只是简单地使用the_program > output.txt来做这件事。然而,所述程序的编码器决定浮华并实时显示处理过的行,使用\b字符来擦除先前的值。因此,output.txt中的一行最终会像Lines: 1(b)2(b)3(b)4(b)5一样,(b)是一个带有ASCII代码08的不可打印字符。我希望该行最终为Lines: 5

我知道我可以按原样编写并对文件using AWK进行后处理,但我想知道是否有可能以某种方式处理控制字符,通过使用某种shell选项或将一些命令组合在一起,这样该行就会变成Lines: 5,而不必在程序完成后运行任何其他命令?

修改

只是澄清一下:我在这里写的是一个简化版本,程序处理的实际行数是十万,所以字符串结尾很长。

1 个答案:

答案 0 :(得分:2)

感谢您的评论!我最终将该程序的输出传递给问题中链接的AWK Script I.我最终得到了一个结构良好的文件。

the_program | ./awk_crush.sh > output.txt

唯一的缺点是,只有在程序本身完成后才能获得输出,即使初始输出超过5M并且应该在较小的块中传递。我不知道确切的原因,也许AWK脚本在stdin上等待EOF。无论哪种方式,在更现代的系统上我会使用

stdbuf -oL the_program | ./awk_crush.sh > output.txt

逐行处理输出。我虽然支持过期支持RHEL4,但我无法同时使用stdbufunbuffer。我会保持原样,也没关系。

awk_crush.sh的内容基于this answer,除了^H序列(应该是通过VIM命令输入的ASCII 08字符)替换为转义序列{{ 1}}:

\b

基本上,它用空字符串替换#!/usr/bin/awk -f function crushify(data) { while (data ~ /[^\b]\b/) { gsub(/[^\b]\b/, "", data) } print data } crushify($0) \b本身之前的字符,并在字符串中有\b时重复它 - 正是我需要的。它并不关心其他的转义序列,但如果有必要的话,还有一个更完整的SED solution来自 Thomas Dickey