我正在使用以下子进程调用来使用命令行工具。命令行工具的输出不会一次打印,它会立即打印在命令行上,它会在一段时间内生成多行。该工具为bs1770gain,命令为“path \ to \ bs1770gain.exe”“ - i”“\ path \ to \ audiofile.wav”,通过使用--loglevel参数,您可以包含更多数据但你无法删除写入stdout的渐进结果。
我需要stdout来返回一个人类可读的字符串(因此stdout_formatted操作):
with subprocess.Popen(list_of_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc:
stdout, stderr = proc.communicate()
stdout_formatted = stdout.decode('UTF-8')
stderr_formatted = stderr.decode('UTF-8')
但是,如果我打印它,我只能将变量视为人类可读的字符串,例如
In [23]: print(stdout_formatted )
nalyzing ... [1/2] "filename.wav":
integrated: -2.73 LUFS / -20.27 LU [2/2]
"filename2.wav":
integrated: -4.47 LUFS / -18.53 LU
[ALBUM]:
integrated: -3.52 LUFS / -19.48 LU done.
In [24]: stdout_formatted
Out[24]: 'a\x00n\x00a\x00l\x00y\x00z\x00i\x00n\x00g\.......
In [6]: stdout
Out[6]: b'a\x00n\x00a\x00l\x00y\x00z\x00i\x00n\x00g\......
In [4]: type(stdout)
Out[4]: bytes
In [5]: type(stdout_formatted)
Out[5]: str
如果仔细观察,人类可读的字符就在字符串中(第一个字是“分析”
我猜测stdout值需要解码/编码,所以我尝试了不同的方法:
stdout_formatted.encode("ascii")
Out[18]: b'a\x00n\x00a\x00l\x00y\x00z\x00i\x00n\x00g
stdout_formatted.encode("utf-8")
Out[17]: b'a\x00n\x00a\x00l\x00y\x00z\x00i\x00n\x00g\
stdout.decode("utf-8")
Out[15]: 'a\x00n\x00a\x00l\x00y\x00z\x00i\x00n\x00g\
stdout.decode("ascii")
Out[14]: 'a\x00n\x00a\x00l\x00y\x00z\x00i\x00n\x00g\
bytes(stdout).decode("ascii")
Out[13]: 'a\x00n\x00a\x00l\x00y\x00z\x00i\x00n\x00g\
我使用了一个名为chardet的库来检查stdout的编码:
import chardet
chardet.detect(stdout)
Out[26]: {'confidence': 1.0, 'encoding': 'ascii', 'language': ''}
我正在使用Windows 10并且正在使用python 3.6(anaconda软件包和它集成的Spyder IDE)。
我现在紧紧抓住稻草 - 在变量中调用print或者删除stdout字符串中不需要的字节码时,是否可以捕获控制台中显示的内容?
答案 0 :(得分:5)
您没有UTF-8数据。你有UTF-16数据。 UTF-16为每个字符使用两个字节; ASCII和Latin-1范围内的字符(例如a
)仍然使用2个字节,但其中一个字节始终是\x00
个NUL字节。
因为UTF-16总是为每个字符使用2个字节,所以它们的顺序开始重要。编码器可以在两个选项之间进行选择;一个被称为Little Endian, the other Big Endian。通常,编码器在一开始就包含Byte Order Mark,以便解码器知道解码时要使用的两个顺序选项中的哪一个。
您发布的数据似乎不包含BOM(我没有看到0xFF
和0xFE
个字节,但您的数据看起来确实使用了小端排序。这是Windows; Windows总是使用little-endian排序为它的UTF-16输出。
如果您的数据确实存在BOM,则可以解码为'utf-16'
。如果缺少BOM,请使用'utf-16-le'
:
>>> sample = b'a\x00n\x00a\x00l\x00y\x00z\x00i\x00n\x00'
>>> sample.decode('utf-16-le')
'analyzin'
>>> import codecs
>>> (codecs.BOM_UTF16_LE + sample)
b'\xff\xfea\x00n\x00a\x00l\x00y\x00z\x00i\x00n\x00'
>>> (codecs.BOM_UTF16_LE + sample).decode('utf-16')
'analyzin'
答案 1 :(得分:-2)
你试过了吗?
str(stdout_formatted).replace('\x00','')