【发布时间】:2019-02-13 21:41:45
【问题描述】:
TL;DR:文本文件包含表示反斜杠转义的字符串;如何将它们用作os.stat() 的输入?
我有一个输入文件input.txt:
./with\backspace
./with\nnewline
用简单的循环处理它们不起作用:
>>> import os
>>> with open('input.txt') as f:
... for line in f:
... os.stat(line.strip())
...
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
FileNotFoundError: [Errno 2] No such file or directory: './with\\backspace'
按照another question 中的建议使用.decode("unicode_escape") 只能部分工作 - 文件中的第一行失败,\n 的第二行没有。
旁注:输入文件名有./,我知道我可以使用os.listdir('.') 并遍历文件直到找到正确的文件。那不是我的目标。目标是处理文件中包含反斜杠转义的文件名。
附加测试:
>>> import os
>>> with open('./input.txt') as f:
... for l in f:
... os.stat(l.strip().decode('unicode_escape'))
...
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
AttributeError: 'str' object has no attribute 'decode'
>>> with open('./input.txt') as f:
... for l in f:
... try:
... os.stat(l.strip().encode('utf-8').decode('unicode_escape'))
... print(l.strip())
... except:
... pass
...
os.stat_result(st_mode=33188, st_ino=1053469, st_dev=2049, st_nlink=1, st_uid=1000, st_gid=1000, st_size=0, st_atime=1536468565, st_mtime=1536468565, st_ctime=1536468565)
./with\nnewline
使用os.fsencode() 编写显式字符串有效:
>>> os.stat(os.fsencode('with\x08ackspace'))
os.stat_result(st_mode=33188, st_ino=1053465, st_dev=2049, st_nlink=1, st_uid=1000, st_gid=1000, st_size=0, st_atime=1536468565, st_mtime=1536468565, st_ctime=1536468565)
但是,由于同一命令有多种变体,我仍然无法从文件中读取字符串,以便 os.stat() 接受它。
>>> with open('./input.txt') as f:
... for l in f:
... os.stat(os.fsdecode( bytes(l.strip(),'utf-8').decode('unicode_escape').encode('latin1') ) )
...
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
FileNotFoundError: [Errno 2] No such file or directory: './with\x08ackslash'
【问题讨论】:
-
请澄清这两个样本的正确结果转换应该是什么。
-
@wallyk 我不确定您所说的“校正结果转换”是什么意思,所以请澄清一下。目标是将每个字符串作为有效路径名传递给
os.stat()。正如您从两个示例中看到的那样,将字符串作为从文件中读取的内容传递并使用.decode()生成一个os.stat()无法解释的字符串。具有此类文件名的文件存在于我的文件系统中,我需要一种 Pythonic 方式来访问它们。这有帮助吗? -
那么
\b是退格还是目录分隔符后跟b? -
@StephenRauch 我在 Linux 上工作,所以它不是目录分隔符。该文件使用
touch$'\b'ackspace'创建。所以文件名中的\b是实际的反斜杠字节。在input.txt这是一个字符串。正如我在问题中提到的,我查看了一个相关问题,该问题建议在字符串上使用.decode('unicode_escape'),但这不起作用。我将编辑一个答案以在一秒钟内添加更多输出 -
我想说在文件名中加入退格是一个非常糟糕的主意。
标签: python filenames text-processing