过滤特殊字符,例如shell输出中的颜色代码

时间:2015-05-24 15:18:22

标签: python shell

我在python中运行shell命令,将其输出记录到文件中,最后在网页上显示。但是也记录了命令输出的颜色样式字符。有没有办法过滤掉颜色样式字符或在网页上正确显示它们?非常感谢!

输出日志:

" 22200K .......\u001b[0m\u001b[91m... .......... ...\u001b[0m\u001b[91m.\u001b[0m\u001b[91m...... .........\u001b[0m\u001b[91m.\u001b[0m\u001b[91m \u001b[0m\u001b[91m.\u001b[0m\u001b[91m.\u001b[0m\u001b[91m.\u001b[0m\u001b[91m.\u001b[0m\u001b[91m...... 50% 28.6K 12m55s"

真实文字:

[INFO][88] 22250K .......... .......... .......... .......... .......... 50% 35.8K 12m53s

4 个答案:

答案 0 :(得分:6)

在不太可能的情况下,如果你有xterm256颜色代码,这将过滤'正常'ansi和xterm256 ansi代码:

import re
print re.sub(r'\x1b(\[.*?[@-~]|\].*?(\x07|\x1b\\))', '', a)

或稍微不那么混淆且更易读的形式:

'(' + CSI + '.*?' + CMD + '|' + OSC + '.*?' + '(' + ST + '|' + BEL + ')' + ')'

完整的测试代码:

import re

tests = [
    u"22200K .......\u001b[0m\u001b[91m... .......... ...\u001b[0m\u001b[91m.\u001b[0m\u001b[91m...... .........\u001b[0m\u001b[91m.\u001b[0m\u001b[91m \u001b[0m\u001b[91m.\u001b[0m\u001b[91m.\u001b[0m\u001b[91m.\u001b[0m\u001b[91m.\u001b[0m\u001b[91m...... 50% 28.6K 12m55s",
    u"=\u001b[m=",
    u"-\u001b]23\u0007-",
]

def trim_ansi(a):
    ESC = r'\x1b'
    CSI = ESC + r'\['
    OSC = ESC + r'\]'
    CMD = '[@-~]'
    ST = ESC + r'\\'
    BEL = r'\x07'
    pattern = '(' + CSI + '.*?' + CMD + '|' + OSC + '.*?' + '(' + ST + '|' + BEL + ')' + ')'
    return re.sub(pattern, '', a)

for t in tests:
    print trim_ansi(t)

答案 1 :(得分:3)

这在大多数情况下都适用:

import re
print re.sub(u'\u001b\[.*?[@-~]', '', a)

<强>更新

  

转义序列以字符ESC开头(ASCII十进制27 /十六进制0x1B /八进制033)。对于两个字符序列,第二个字符在ASCII 64-95(@到_)范围内。   但是,大多数序列都是两个以上的字符,并以字符ESC和[(左括号)开头。该序列称为控制序列导入器(或控制序列启动器)的CSI。这些序列的最后一个字符在ASCII 64-126(@到〜)范围内。   (http://en.wikipedia.org/wiki/ANSI_escape_code

<强> UPDATE2

使用以下&#39; a.py&#39;:

import sys, re

for line in sys.stdin:
    sys.stdout.write(re.sub(u'\u001b\[.*?[@-~]', '', line))

这对我来说很顺利:

ls --color | python a.py

答案 2 :(得分:1)

答案 3 :(得分:-1)

您只需通过strings管道输出即可删除任何不可打印的字符:

./some-script | strings