20

我正在尝试获取程序(具有颜色)的输出并使用tee. 我希望输出在终端(stdout)上有颜色,但在输出文件上没有。这可能吗?

4

2 回答 2

4

一种可能的方法是,在 stderr 上打印转义字符,在 stdout 上打印主要内容。我已经在其中一个脚本中完成了它。这当然不是一个可扩展的选项。

编写一个专门的脚本来解析标准输入,将转义序列放在标准错误上,其他的放在标准输出上,这将是一个有趣的练习。:-)
然后 ./myScript.sh | filter_escapes | tee outfile.log
我还没有看到任何脚本可以做到这一点,但我认为,如果还没有的话,写一个会很有趣。

就您的问题而言,我认为以下就足够了:

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

ls --color=always用 ./your_script &替换/tmp/test为您想要的输出文件名。

其他实现:

ls --color=always | tee >(sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' > /tmp/abcd)

注意:tee >(sed .... > logfile)语法

笔记:

  1. 正则表达式借鉴了 sampson-chen 的回答。
  2. sed 中 /dev/stderr 的 w 命令是 GNU sed 的补充。
于 2012-11-07T08:15:11.830 回答
1

是的,这是可能的。通过管道将您想要进入输出文件的结果sed删除用于格式化颜色的转义字符:

在 Linux 上:

sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" 

在 OS X 上,因为它不是 GNU sed:

sed -E "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" 

我最近编写的工具的一部分完全符合您的描述tee

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)

其中函数remove_escaped_chars包含对操作系统版本的检查,然后应用sed如上所示的脚本。

(注1:tee自动将输出的副本重定向到stdout,所以我曾经>$sack__dev_null阻止这种情况:因为我想向打印到stdout的内容添加附加信息,如函数中定义的那样display_shortcuts

(注 2:tee当我使用它时,它本身绝对不会删除颜色格式:我怀疑是其他工具对管道的默认行为。)

于 2012-11-06T17:06:25.160 回答