为什么文本文件行中的“\x01\x1A”(Start-of-Header 和替换控制字符)会过早地停止 for-loop?
Why does '\x01\x1A' (Start-of-Header and Substitute control characters) in a textfile line stop a for-loop prematurely?
我正在使用 Python 2.7.15,Windows 7
上下文
我编写了一个脚本来读取 FileZilla 日志文件(规范 here)的每一行并将其标记为发起与 FileZilla 服务器的连接的主机的 IP 地址。我在解析 >
字符后的 log text
字段时遇到问题。我写的脚本使用了:
with open('fz.log','r') as rh:
for lineno, line in rh:
pass
构造以读取每一行。 for-loop 在遇到包含 SOH
和 SUB
字符的 log text
字段时过早停止。我无法向您显示日志文件,因为它包含敏感信息,但问题的关键可以通过读取包含这些字符的文本文件来重现。
我的目标是提取 IP 地址(我可以使用 re.search()
来完成)但在此之前,我必须删除那些控制字符。为此,我创建了一份日志文件副本,其中包含这些控制字符的行已被删除。可能有更好的方法,但我更好奇为什么 for-loop 在遇到控制字符后就停止了。
重现问题
我用这段代码重现了问题:
if __name__ == '__main__':
fn = 'writetest.txt'
fn2 = 'writetest_NoControlChars.txt'
# Create the problematic textfile
with open(fn, 'w') as wh:
wh.write("This line comes first!\n");
wh.write("Blah\x01\x1A\n"); # Write Start-of-Header and Subsitute unicode character to line
wh.write("This comes after!")
# Try to read the file above, removing the SOH/SUB characters if encountered
with open(fn, 'r') as rh:
with open(fn2, 'w') as wh:
for lineno, line in enumerate(rh):
sline = line.translate(None,'\x01\x1A')
wh.write(sline)
print "Line #{}: {}".format(lineno, sline)
print "Program executed."
输出
上面的代码创建了 2 个输出文件并在控制台中生成以下内容 window:
Line #0: This line comes first!
Line #1: Blah
Program executed.
我 step-debugged 通过 Eclipse 中的代码并在执行
后立即
for lineno, line in enumerate(rh):
语句,rh
,打开的文件的句柄已关闭。我原以为它会移到第三行,打印出 This comes after!
以进行控制台并将其写出到 writetest_NoControlChars.txt
但两个事件都没有发生。相反,执行跳转到 print "Program executed"
。
Picture of Local Variable values in Debug Console
如果您知道此文件包含非文本数据,则必须以二进制模式打开此文件:open(fn, 'rb')
我正在使用 Python 2.7.15,Windows 7
上下文
我编写了一个脚本来读取 FileZilla 日志文件(规范 here)的每一行并将其标记为发起与 FileZilla 服务器的连接的主机的 IP 地址。我在解析 >
字符后的 log text
字段时遇到问题。我写的脚本使用了:
with open('fz.log','r') as rh:
for lineno, line in rh:
pass
构造以读取每一行。 for-loop 在遇到包含 SOH
和 SUB
字符的 log text
字段时过早停止。我无法向您显示日志文件,因为它包含敏感信息,但问题的关键可以通过读取包含这些字符的文本文件来重现。
我的目标是提取 IP 地址(我可以使用 re.search()
来完成)但在此之前,我必须删除那些控制字符。为此,我创建了一份日志文件副本,其中包含这些控制字符的行已被删除。可能有更好的方法,但我更好奇为什么 for-loop 在遇到控制字符后就停止了。
重现问题
我用这段代码重现了问题:
if __name__ == '__main__':
fn = 'writetest.txt'
fn2 = 'writetest_NoControlChars.txt'
# Create the problematic textfile
with open(fn, 'w') as wh:
wh.write("This line comes first!\n");
wh.write("Blah\x01\x1A\n"); # Write Start-of-Header and Subsitute unicode character to line
wh.write("This comes after!")
# Try to read the file above, removing the SOH/SUB characters if encountered
with open(fn, 'r') as rh:
with open(fn2, 'w') as wh:
for lineno, line in enumerate(rh):
sline = line.translate(None,'\x01\x1A')
wh.write(sline)
print "Line #{}: {}".format(lineno, sline)
print "Program executed."
输出
上面的代码创建了 2 个输出文件并在控制台中生成以下内容 window:
Line #0: This line comes first!
Line #1: Blah
Program executed.
我 step-debugged 通过 Eclipse 中的代码并在执行
后立即for lineno, line in enumerate(rh):
语句,rh
,打开的文件的句柄已关闭。我原以为它会移到第三行,打印出 This comes after!
以进行控制台并将其写出到 writetest_NoControlChars.txt
但两个事件都没有发生。相反,执行跳转到 print "Program executed"
。
Picture of Local Variable values in Debug Console
如果您知道此文件包含非文本数据,则必须以二进制模式打开此文件:open(fn, 'rb')