一种可能的方法是,在 stderr 上打印转义字符,并在 stdout 上打印主要内容。我在其中一个剧本中做到了这一点。这当然不是一个可扩展的选项。
编写一个专用脚本来解析 stdin,将转义序列放在 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
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
注意:tee >(sed .... > logfile)语法
笔记:
是的,这是可能的。将要进入输出文件的结果通过管道传输,sed以删除格式化颜色中使用的转义字符:
在 Linux 上:
sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
Run Code Online (Sandbox Code Playgroud)
在 OS X 上,因为它不是 GNU sed:
sed -E "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
Run Code Online (Sandbox Code Playgroud)
我最近编写的工具的一部分完全符合您的描述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)
Run Code Online (Sandbox Code Playgroud)
其中该函数remove_escaped_chars包含对操作系统版本的检查,然后应用sed如上所示的脚本。
(注 1:tee自动将输出的副本重定向到 stdout,因此我过去常常>$sack__dev_null防止这种情况发生:因为我想向打印到 stdout 的内容添加附加信息,如函数中所定义display_shortcuts)
(注2:tee当我使用它时,它本身绝对不会删除颜色格式:我怀疑是其他工具对管道的默认行为。)