如何用Regex移除脚本输出中的ANSI转义序列?
问题描述
需要编写正则表达式清理脚本输出中的特殊字符,移除所有以[开头、以m或;结尾的子串,同时清理其他控制字符(如^M、^G等)。
原始脚本输出:
Script started on 2023-09-16 10:06:45-04:00 [TERM="xterm-256color" TTY="/dev/pts/1" COLUMNS="204" LINES="55"] ^[[?2004h^[]0;matt@SERENITY: ~^G^[[01;32mmatt@SERENITY^[[00m:^[~^[[00m$ ls^M ^[[?2004l^M^[[0m^[Desktop^[[0m ^[[01;34mDocuments^[[0m ^[[01;34mDownloads^[[0m ^[[01;34mmarkdown^[[0m ^[[01;34mMusic^[[0m ^[[01;34mnotes^[[0m ^[[01;34mPictures^[[0m ^[[01;34mPublic^[[0m ^[[01;34mscripts^[[0m ^[[01;34msnap^[[0m ^[[01;34mTemplates^[[0m typescript ^[[01;34mVideos^[[0m^M ^[[?2004h^[]0;matt@SERENITY: ~^G^[[01;32mmatt@SERENITY^[[00m:^[~^[[00m$ ls^M ^[[?2004l^M^[[0m^[Desktop^[[0m ^[[01;34mDocuments^[[0m ^[[01;34mDownloads^[[0m ^[[01;34mmarkdown^[[0m ^[[01;34mMusic^[[0m ^[[01;34mnotes^[[0m ^[[01;34mPictures^[[0m ^[[01;34mPublic^[[0m ^[[01;34mscripts^[[0m ^[[01;34msnap^[[0m ^[[01;34mTemplates^[[0m typescript ^[[01;34mVideos^[[0m^M ^[[?2004h^[]0;matt@SERENITY: ~^G^[[01;32mmatt@SERENITY^[[00m:^[~^[[00m$ ls^M ^[[?2004l^M^[[0m^[Desktop^[[0m ^[[01;34mDocuments^[[0m ^[[01;34mDownloads^[[0m ^[[01;34mmarkdown^[[0m ^[[01;34mMusic^[[0m ^[[01;34mnotes^[[0m ^[[01;34mPictures^[[0m ^[[01;34mPublic^[[0m ^[[01;34mscripts^[[0m ^[[01;34msnap^[[0m ^[[01;34mTemplates^[[0m typescript ^[[01;34mVideos^[[0m^M ^[[?2004h^[]0;matt@SERENITY: ~^G^[[01;32mmatt@SERENITY^[[00m:^[~^[[00m$ exit^M ^[[?2004l^Mexit^M Script done on 2023-09-16 10:06:49-04:00 [COMMAND_EXIT_CODE="0"]
当前使用的命令(过于重复):
%s:/^M\|^G\|^[//g | %s/\[01;34m//g | %s/\[01;32m//g
期望输出:
Script started on 2023-09-16 10:06:45-04:00 [TERM="xterm-256color" TTY="/dev/pts/1" COLUMNS="204" LINES="55"] matt@SERENITY: ~matt@SERENITY:~$ ls Desktop Documents Downloads markdown Music notes Pictures Public scripts snap Templates typescript Videos matt@SERENITY: ~matt@SERENITY:~$ ls Desktop Documents Downloads markdown Music notes Pictures Public scripts snap Templates typescript Videos matt@SERENITY: ~matt@SERENITY:~$ ls Desktop Documents Downloads markdown Music notes Pictures Public scripts snap Templates typescript Videos matt@SERENITY: ~matt@SERENITY:~$ exit exit Script done on 2023-09-16 10:06:49-04:00 [COMMAND_EXIT_CODE="0"]
解决方案
可以用一条更简洁的正则替换命令,一次性处理所有目标特殊字符:
Vim环境下的完整替换命令
%s/\(\^\[\|\[\)[^m;]*[m;]\|^\M\|^\G//g
命令解释
\(\^\[\|\[\):匹配两种开头情况:要么是^[(ESC字符,在Vim中输入Ctrl+V再按ESC),要么是普通的[[^m;]*:匹配任意数量(包括0个)非m和非;的字符[m;]:匹配结尾的m或;\|^\M\|^\G:同时匹配并移除^M(回车字符,Vim中输入Ctrl+V再按回车)和^G(响铃字符,Vim中输入Ctrl+V再按Ctrl+G)//g:全局替换,所有匹配项都替换为空
其他正则环境(如sed)的适配命令
sed -e 's/\(\x1b\|\[\)[^m;]*[m;]//g' -e 's/\r//g' -e 's/\x07//g' your_script_output.txt
适配说明
\x1b代表ESC字符(对应原文本中的^[)\r代表^M回车字符\x07代表^G响铃字符
执行上述命令后即可一次性清理所有目标特殊字符,得到符合预期的干净输出。
内容的提问来源于stack exchange,提问作者Mathew
相关产品推荐
相关产品推荐

