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'
答案 0 :(得分:1)
在macOS中工作:
touch $'with\backspace'
touch $'with\newline'
echo $'./with\\backspace\n./with\\newline' > input.txt
python
>>> import os
>>> with open('./input.txt') as f:
... for l in f:
... os.stat(l.strip().decode('unicode_escape'))
posix.stat_result(st_mode=33188, st_ino=8604304962, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=0, st_atime=1536469815, st_mtime=1536469815, st_ctime=1536469815)
posix.stat_result(st_mode=33188, st_ino=8604305024, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=0, st_atime=1536470112, st_mtime=1536470112, st_ctime=1536470112)
那是达尔文内核版本17.7.0上的Python 2.7.14。
答案 1 :(得分:0)
经过大约2个小时的了解,我意识到输入文件包含./with\backslash
,而实际文件名是通过touch with$'\b'ackspace
创建的。因此Health Raftery's answer有效,但仅适用于Python2。在Python 3中,由于字符串in Python 3 are already a unicode strings而获得AttributeError: 'str' object has no attribute 'decode'
。
在此过程中,我可能通过os.fsencode()找到了更好的方法 在jfs's answer中引用。
import os
with open('./input.txt') as f:
for l in f:
# alternatively one can use
# bytes(l.strip(),sys.getdefaultencoding())
bytes_filename = bytes(l.strip(), 'utf-8').decode('unicode_escape')
f_stat = os.stat(os.fsdecode( bytes_filename ) )
print(l.strip(),f_stat)
由于我主要使用Python 3,所以这就是我想要的。但是,Health Raftery's answer仍然有效,因此已被+1。