如何使用glob读取有限的数字文件名集?
如何使用glob只读取有限数量的文件?
我有一些json文件,文件名是从50到20000的数字(比如50.json、51.json、52.json……一直到19999.json和20000.json),它们都在同一个文件夹里。我想只读取编号在15000到18000之间的文件。
为此,我正在使用glob,下面是我的代码,但每次我尝试过滤这些数字时,它都会生成一个空列表。我已经尽力按照这个链接的说明去做(https://docs.python.org/2/library/glob.html),但我不太确定哪里出了问题。
>>> directory = "/Users/Chris/Dropbox"
>>> read_files = glob.glob(directory+"/[15000-18000].*")
>>> print read_files
[]
另外,如果我想要读取任何大于18000的文件呢?
3 个回答
我修改了@martineau的代码,因为我在使用我的文件时遇到了一个错误,正则表达式返回了一个空数组(可能是因为我在用Python 3?)。我还把输出改成用空格分隔,这样可以在Linux命令行中使用,比如:
cp `python readfiles.py` mydir
反引号会执行里面的命令,并把输出插入到命令行中。这假设返回的文件名中没有空格。
这是修改后的代码:
Import os, re
directory = "."
all_files = os.listdir(directory)
read_files = [this_file for this_file in all_files
if re.search(r'\d+', this_file) and int(re.findall(r'\d+', this_file)[-1]) > 18000
]
print(' '.join(read_files))
虽然这段代码可能不算特别优雅,但你可以按照下面的方式自己实现过滤功能:
import os, re
directory = "/Users/Chris/Dropbox"
all_files = os.listdir(directory)
read_files = [this_file for this_file in all_files
if (int(re.findall('\d+', this_file)[-1]) > 18000)]
print read_files
这里最关键的一行是(for this_file in all_files
),它会遍历目录中的每个文件名,然后提取出文件名中的数字部分(re.findall('\d+', this_file)
)。如果这些数字中的最后一个数字(转换为整数后)大于18000,就会把这个文件名加入到read_files
中。
我觉得如果文件名中没有数字,这段代码可能会出问题,所以使用时要小心。
补充:我看到之前的回答已经被修改,加入了一种看起来更合理的做法。
你在使用通配符语法的时候搞错了;[..]
这个部分是按每个字符来处理的。下面这个通配符可以正确匹配你的文件:
'1[5-8][0-9][0-9][0-9].*'
其实,glob
这个工具在后台使用的是fnmatch
,它会把你的模式转换成正则表达式。你的模式转换成了:
>>> import fnmatch
>>> fnmatch.translate('[15000-18000].*')
'[15000-18000]\\..*\\Z(?ms)'
这个表达式会匹配一个字符在.
之前,后面跟着0
、1
、5
或者8
。其他的都不行。
glob
的模式功能比较有限;用它来匹配数字范围并不简单;你需要为每个范围创建单独的通配符,比如说(glob('1[8-9][0-9][0-9][0-9]') + glob('2[0-9][0-9][0-9][0-9]')
,等等)。
不如自己来过滤一下:
directory = "/Users/Chris/Dropbox"
for filename in os.listdir(directory):
basename, ext = os.path.splitext(filename)
if ext != '.json':
continue
try:
number = int(basename)
except ValueError:
continue # not numeric
if 18000 <= number <= 19000:
# process file
filename = os.path.join(directory, filename)