获取目录中文件的过滤列表

我正在尝试使用Python获取目录中的文件列表,但我不想要所有文件的列表。

我基本上想要的是能够做以下的事情,但是使用Python而不是执行ls。

ls 145592*.jpg 

如果没有内置的方法,我现在想写一个for循环遍历os.listdir()的结果,并将所有匹配的文件追加到一个新的列表。

但是,该目录中有很多文件,因此我希望有一个更有效的方法(或内置方法)。

glob.glob('145592*.jpg')

glob.glob()绝对是这样做的(按照Ignacio)。 但是,如果你确实需要更复杂的匹配,你可以用列表理解和re.match() ,就像这样:

 files = [f for f in os.listdir('.') if re.match(r'[0-9]+.*\.jpg', f)] 

更灵活,但正如你注意到的那样,效率较低。

把事情简单化:

 import os relevant_path = "[path to folder]" included_extenstions = ['jpg', 'bmp', 'png', 'gif'] file_names = [fn for fn in os.listdir(relevant_path) if any(fn.endswith(ext) for ext in included_extensions)] 

我更喜欢这种列表parsing的forms,因为它的英文读法很好。

我读了第四行:对于我的pathos.listdir中的每个fn,给我只有那些匹配我的任何一个扩展。

新手python程序员可能很难真正习惯于使用列表推导来进行过滤,并且它可能对于非常大的数据集有一些内存开销,但是为了列出一个目录和其他简单的string过滤任务,list列表理解会导致更加清洁可描述的代码。

这个devise唯一的事情就是它不会保护你不会传递一个string而不是一个列表的错误。 例如,如果您不小心将string转换为列表并最终检查string的所有字符,最终可能会产生大量的误报。

但是,比起一个难以理解的解决scheme,有一个容易解决的问题更好。

另外一个select:

 >>> import os, fnmatch >>> fnmatch.filter(os.listdir('.'), '*.py') ['manage.py'] 

https://docs.python.org/3/library/fnmatch.html

使用os.walkrecursion列出你的文件

 import os root = "/home" pattern = "145992" alist_filter = ['jpg','bmp','png','gif'] path=os.path.join(root,"mydir_to_scan") for r,d,f in os.walk(path): for file in f: if file[-3:] in alist_filter and pattern in file: print os.path.join(root,file) 

初步的代码

 import glob import fnmatch import pathlib import os pattern = '*.py' path = '.' 

解决scheme1 – 使用“glob”

 # lookup in current dir glob.glob(pattern) In [2]: glob.glob(pattern) Out[2]: ['wsgi.py', 'manage.py', 'tasks.py'] 

解决scheme2 – 使用“os”+“fnmatch”

变种2.1 – 在当前目录中查找

 # lookup in current dir fnmatch.filter(os.listdir(path), pattern) In [3]: fnmatch.filter(os.listdir(path), pattern) Out[3]: ['wsgi.py', 'manage.py', 'tasks.py'] 

变种2.2 – 查找recursion#查找recursion为dirpath,dirnames,在os.walk文件名(path):

  if not filenames: continue pythonic_files = fnmatch.filter(filenames, pattern) if pythonic_files: for file in pythonic_files: print('{}/{}'.format(dirpath, file)) 

结果

 ./wsgi.py ./manage.py ./tasks.py ./temp/temp.py ./apps/diaries/urls.py ./apps/diaries/signals.py ./apps/diaries/actions.py ./apps/diaries/querysets.py ./apps/library/tests/test_forms.py ./apps/library/migrations/0001_initial.py ./apps/polls/views.py ./apps/polls/formsets.py ./apps/polls/reports.py ./apps/polls/admin.py 

解决scheme3 – 使用“pathlib”

 # lookup in current dir path_ = pathlib.Path('.') tuple(path_.glob(pattern)) # lookup recursive tuple(path_.rglob(pattern)) 

笔记:

  1. 在Python 3.4上testing
  2. 模块“pathlib”仅在Python 3.4中添加
  3. Python 3.5为glob.glob添加了一个recursion查找functionhttps://docs.python.org/3.5/library/glob.html#glob.glob 。 由于我在我的机器上安装了Python 3.4,所以我无法testing它。
 import os dir="/path/to/dir" [x[0]+"/"+f for x in os.walk(dir) for f in x[2] if f.endswith(".jpg")] 

这会给你一个完整path的jpg文件列表。 你可以用f代替x[0]+"/"+f来表示文件名。 你也可以用你想要的任何string条件replacef.endswith(".jpg")

你可能也喜欢更高级的方法(我已经实现并打包为findtools ):

 from findtools.find_files import (find_files, Match) # Recursively find all *.txt files in **/home/** txt_files_pattern = Match(filetype='f', name='*.txt') found_files = find_files(path='/home', match=txt_files_pattern) for found_file in found_files: print found_file 

可以安装

 pip install findtools 

你可以使用subprocess.check_ouput()作为

 import subprocess list_files = subprocess.check_output("ls 145992*.jpg", shell=True) 

当然,引号之间的string可以是任何你想在shell中执行的内容,并存储输出。