我的程序正在将字符颜色文本发送到某个日志文件:
echo -e "\\033[38;5;2m-->\\033[0m Starting program." | tee $LogFile -a
结果是一个完美的彩色日志行,但我想同时创建另一个没有 ANSI 代码的日志文件,因为我需要在 Windows 中浏览此日志(我知道有一些 ANSI 浏览器可以用于Windows,但我更喜欢使用 Total Commander 浏览日志文件,它没有合适的插件)。
因此,我的日志行中需要三个输出:
- 一些彩色
-->启动程序。
行到屏幕。 - 将相同颜色的
--> 启动程序。
行添加到带有 ANSI 代码的日志文件中。 - 与日志文件相同的未着色
-->启动程序。
行(据说没有ANSI代码,或者我认为是这样)。
由于 tee
命令,上面的行很好,它解决了第 1 点和第 2 点,但我不知道如何添加一些选项来保存到另一个文件,但没有 ANSI 代码,位于至少没有复制整行。
也许在 mkfifo 的帮助下使用重定向器、文件描述符?
顺便说一句,我现在的解决方法是重复输出(这变得有点尴尬):
echo -e "\\033[38;5;2m--> Starting program.\\033[0m" | tee $LogFile -a
echo "--> Starting program." >> $NotANSILogFile
最佳答案
要将 ansi 代码发送到日志文件,ansi.log
,并显示到屏幕,同时还将非 ansi 版本发送到名为 nonansi.log
的日志文件。 ,使用:
echo -e "\\033[38;5;2m-->\\033[0m Starting program." | tee -a ansi.log | tee /dev/tty | sed $'s/\E[^m]*m//g' >>nonansi.log
它是如何工作的
tee -a ansi.log
第一个
tee
命令将 ansi 编码的字符串附加到日志文件ansi.log
.tee /dev/tty
第二个
tee
命令将 ansi 编码的字符串发送到屏幕。 (/dev/tty
是当前屏幕的文件名。)sed $'s/\E[^m]*m//g' >>nonansi.log
最终命令,
sed
删除 ansi 序列并将结果附加到nonansi.log
.sed
命令包含在bash
中$'...'
字符串,以便转义字符可以简单地表示为\E
。此替代命令查找以转义符\E
开头的序列。 ,并以m
结尾并删除它们。决赛g
告诉sed
对行上的每个转义序列执行此替换,而不仅仅是第一个。如果你有 GNU
sed
,另一种方法是使用 GNU 的\o
改为符号:sed 's/\o033[^m]*m//g' >>nonansi.log
如果您没有 GNU
sed
也不bash
,那么你需要看看你的sed
有什么设施或者您的 shell 提供了 Esc 字符。
在 shell 函数中隐藏详细信息
如果您需要创建多个日志条目,最简单的方法可能是创建一个 shell 函数 logger
,保存所有凌乱的细节:
logger() { echo -e "$*" | tee -a ansi.log | tee /dev/tty | sed $'s/\E[^m]*m//g' >>nonansi.log; }
定义此函数后,可以通过提供 ansi 编码字符串作为参数来执行任何日志条目:
logger "\\033[38;5;2m-->\\033[0m Start."
关于shell - 将 ANSI 彩色代码文本发送到 3 个输出 : screen, 文件和文件过滤 ANSI 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27464492/