bash 使用 tee 输出时保留颜色
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/13255642/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Preserve color when outputting with tee
提问by pap42
I'm trying to get the output of a program (which has colors) and output it with tee. I want the output to have colors on the terminal (stdout) but not on the output file. Is this possible?
我正在尝试获取程序的输出(具有颜色)并使用tee. 我希望输出在终端 (stdout) 上有颜色,但在输出文件上没有。这可能吗?
回答by anishsane
A possible approach is, to print the escape characters on stderr, & main contents on stdout. I had done it in one of the script. It's off course not a scalable option.
一种可能的方法是,在 stderr 上打印转义字符,在 stdout 上打印主要内容。我已经在其中一个脚本中完成了。这当然不是一个可扩展的选项。
It would be an interesting exercise to write a dedicated script, which parses stdin, puts escape sequences on stderr & others on stdout. :-)
Then 
./myScript.sh | filter_escapes | tee outfile.log
I have not seen any script which does that, but I think, it would be interesting to write one, if not already available.
编写一个专门的脚本来解析 stdin,将转义序列放在 stderr 上,将转义序列放在 stdout 上,这将是一个有趣的练习。:-)
那么 
./myScript.sh | filter_escapes | tee outfile.log
我还没有看到任何可以做到这一点的脚本,但我认为,如果还没有的话,写一个会很有趣。
As far as your question is concerned, I think below should suffice:
就你的问题而言,我认为以下就足够了:
ls --color=always | sed -r 'w /dev/stderr' | sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' > /tmp/test
replace ls --color=alwayswith ./your_script & /tmp/testwith your intended output file name.
ls --color=always用 ./your_script &替换为/tmp/test您想要的输出文件名。
Other implementation:
其他实现:
ls --color=always | tee >(sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' > /tmp/abcd)
Note: tee >(sed .... > logfile)syntax 
注意:tee >(sed .... > logfile)语法
Note:
1. regex borrowed from sampson-chen's answer.
2. w command for /dev/stderr in sed is GNU sed's addition.
注意:
1. 正则表达式借自 sampson-chen 的回答。
2. sed 中 /dev/stderr 的 w 命令是 GNU sed 的补充。
回答by sampson-chen
Yes, it's possible. Pipe the results you want to go into the output file through sedto remove the escape characters used in formatting colors:
是的,这是可能的。将您想要进入输出文件的结果通过管道传输sed以删除用于格式化颜色的转义字符:
On Linux:
在 Linux 上:
sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" 
On OS X since it's not GNU sed:
在 OS X 上,因为它不是 GNU sed:
sed -E "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" 
A part of a tool I wrote recently does exactly what you described with tee: 
我最近编写的工具的一部分完全符合您的描述tee:
https://github.com/sampson-chen/sack/blob/master/sack
https://github.com/sampson-chen/sack/blob/master/sack
 ack --color $sack__flags $@ $sack__cwd | tee >$sack__dev_null >(display_shortcuts) >(process_shorcut_paths | remove_escaped_chars > $sack__shortcut_file)
where the function remove_escaped_charscontains a check for OS version, then applies the sedscript as seen above.
其中函数remove_escaped_chars包含对操作系统版本的检查,然后应用sed如上所示的脚本。
(Note 1: teeredirects a copy of output to stdout automatically, so I used >$sack__dev_nullto prevent that: because I wanted add additional information to the stuff printed to stdout, as defined in the function display_shortcuts)
(注 1:tee自动将输出的副本重定向到 stdout,所以我曾经>$sack__dev_null阻止:因为我想向打印到 stdout 的内容添加附加信息,如函数中所定义display_shortcuts)
(Note 2: teeitself definitely never removed the color formatting when I used it: My suspicion is other tools' default behaviour with pipes.)
(注 2:tee当我使用它时,它本身绝对不会删除颜色格式:我怀疑其他工具的默认行为是管道。)

