我想用Python 3脚本(在Linux上)逐行处理正在运行的程序的输出(想象tail -f
)。
程序输出,通过管道输出到脚本,用latin-1编码,因此,在Python 2中,我使用codecs
模块正确解码sys.stdin
的输入:< / p>
#!/usr/bin/env python
import sys, codecs
sin = codecs.getreader('latin-1')(sys.stdin)
for line in sin:
print '%s "%s"' % (type (line), line.encode('ascii','xmlcharrefreplace').strip())
这有效:
<type 'unicode'> "Hi! öäß"
...
然而,在Python 3中,sys.stdin.encoding
是UTF-8
,如果我只是从stdin中天真地读过:
#!/usr/bin/env python3
import sys
for line in sys.stdin:
print ('type:{0} line:{1}'.format(type (line), line))
我收到此错误:
UnicodeDecodeError: 'utf8' codec can't decode byte 0xf6 in position 4: invalid start byte
如何在Python 3中读取通过管道传输到stdin的非UTF-8文本数据?
答案 0 :(得分:3)
import sys
import io
with io.open(sys.stdin.fileno(),'r',encoding='latin-1') as sin:
for line in sin:
print ('type:{0} line:{1}'.format(type (line), line))
产量
type:<class 'str'> line:Hi! öäß
答案 1 :(得分:2)
请查看文档中的此链接:sys.stdin。相关部分是:
默认情况下,标准流处于文本模式。要将二进制数据写入或读取,请使用基础二进制缓冲区。例如,要将字节写入stdout,请使用sys.stdout.buffer.write(b'abc')。使用io.TextIOBase.detach()流可以默认为二进制。此函数将stdin和stdout设置为binary:
def make_streams_binary():
sys.stdin = sys.stdin.detach()
sys.stdout = sys.stdout.detach()
执行此操作后,您可以将二进制输入编码为您想要的任何编码。
另见这篇文章:
How to set sys.stdout encoding in Python 3?
该帖子的建议是使用:
sys.stdin = codecs.getreader("utf-8")(sys.stdin.detach())