我的程序正在将字符颜色文本发送到某个日志文件:
echo -e "\\033[38;5;2m-->\\033[0m Starting program." | tee $LogFile -a
导致完美彩色的日志行,但我想同时创建另一个没有ANSI 代码的日志文件,因为我需要在Windows中浏览此日志(我知道有一些ANSI浏览器用于Windows,但我更喜欢使用Total Commander浏览日志文件,它没有合适的插件。
所以,我的日志行中需要三个输出:
--> Starting program.
行到屏幕。--> Starting program.
行。--> Starting program.
行(据说没有ANSI 代码,或者我认为是这样)。由于tee
命令解决了第1点和第2点,上面的行很好,但我不知道如何添加一些选项来保存到另一个文件但没有ANSI代码,至少没有< strong>复制整行。
也许在mkfifo的帮助下使用重定向器,文件描述符?
顺便说一句,我现在的解决方法是输出重复(有点尴尬):
echo -e "\\033[38;5;2m--> Starting program.\\033[0m" | tee $LogFile -a
echo "--> Starting program." >> $NotANSILogFile
答案 0 :(得分:3)
要将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
。此替换命令查找以escape \E
开头,以m
结尾的序列,并将其删除。最后的g
告诉sed
对该行的每个转义序列执行此替换,而不仅仅是第一个。
如果你有GNU sed
,另一种方法是使用GNU的\o
符号代替:
sed 's/\o033[^m]*m//g' >>nonansi.log
如果您既没有GNU sed
也没有bash
,那么您需要查看sed
或您的shell为Esc字符提供的设施。
如果您需要创建多个日志条目,最简单的方法是创建一个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."
答案 1 :(得分:2)
此方法有效(需要安装perl
)才能将输出发送到屏幕(ANSI)和两个文件:$LogFile
(ANSI)和$LogFile.plain
(不含ANSI):
echo -e "\\033[38;5;2m--> Starting program.\\033[0m" | tee >(perl -pe 's/\e\[?.*?[\@-~]//g'>>"$LogFile".plain) $LogFile -a
详细信息:
tee
命令将输出拆分为屏幕(stdout)和perl
命令。perl
行过滤ANSI代码。perl
的输出被重定向到普通的非ANSI日志文件(使用LogFile.plain
作为其文件名)。仅将输出发送到文件(不是屏幕)(仅与经典>/dev/null
相同)。
echo -e "\\033[38;5;2m--> Starting program.\\033[0m" | tee >(perl -pe 's/\e\[?.*?[\@-~]//g'>>"$LogFile".plain) $LogFile -a >/dev/null
注意:
>>
代替>
,正如增量日志文件所期望的那样。-a
命令使用了tee
,原因与上述相同。sed
代替perl
,但到目前为止我找到的所有sed
示例都不起作用。如果有人知道,请报告。