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

时间:2010-02-08 23:02:56

标签: python filesystems wildcard glob directory-listing

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

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

ls 145592*.jpg

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

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

14 个答案:

答案 0 :(得分:308)

答案 1 :(得分:108)

glob.glob()绝对是这样做的方法(根据Ignacio)。但是,如果你确实需要更复杂的匹配,你可以使用列表推导和re.match()来实现,如下所示:

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

更灵活,但正如您所说,效率较低。

答案 2 :(得分:36)

保持简单:

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

我更喜欢这种列表推导形式,因为它用英语读得很好。

我读了第四行:   对于我的路径的os.listdir中的每个fn,只给我匹配任何一个包含的扩展名。

新手python程序员可能很难真正习惯使用列表推导进行过滤,并且它可能会为非常大的数据集带来一些内存开销,但是为了列出目录和其他简单的字符串过滤任务,list comprehensions lead更清洁的可记录代码。

这个设计的唯一之处在于它不能保护你免于犯错传递字符串而不是列表。例如,如果您不小心将字符串转换为列表并最终检查字符串的所有字符,则最终可能会出现大量误报。

但是,与一个难以理解的解决方案相比,最好有一个容易解决的问题。

答案 3 :(得分:30)

另一种选择:

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

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

答案 4 :(得分:8)

使用os.walk以递归方式列出您的文件

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)

答案 5 :(得分:8)

初步代码

import glob
import fnmatch
import pathlib
import os

pattern = '*.py'
path = '.'

解决方案1 ​​ - 使用" glob"

# lookup in current dir
glob.glob(pattern)

In [2]: glob.glob(pattern)
Out[2]: ['wsgi.py', 'manage.py', 'tasks.py']

解决方案2 - 使用" 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']

Variant 2.2 - 查找递归

# lookup recursive
for dirpath, dirnames, filenames in 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

解决方案3 - 使用" pathlib"

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

# lookup recursive
tuple(path_.rglob(pattern))

注意:

  1. 在Python 3.4上测试
  2. 模块" pathlib"仅在Python 3.4中添加。
  3. Python 3.5添加了一个使用glob.glob进行递归查找的功能 https://docs.python.org/3.5/library/glob.html#glob.glob。由于我的机器安装了Python 3.4,我还没有测试过。

答案 6 :(得分:3)

使用glob模块进行过滤:

导入glob

import glob

通配符:

files=glob.glob("data/*")
print(files)

Out:

['data/ks_10000_0', 'data/ks_1000_0', 'data/ks_100_0', 'data/ks_100_1',
'data/ks_100_2', 'data/ks_106_0', 'data/ks_19_0', 'data/ks_200_0', 'data/ks_200_1', 
'data/ks_300_0', 'data/ks_30_0', 'data/ks_400_0', 'data/ks_40_0', 'data/ks_45_0', 
'data/ks_4_0', 'data/ks_500_0', 'data/ks_50_0', 'data/ks_50_1', 'data/ks_60_0', 
'data/ks_82_0', 'data/ks_lecture_dp_1', 'data/ks_lecture_dp_2']

扩展名.txt

files = glob.glob("/home/ach/*/*.txt")

一个字符

glob.glob("/home/ach/file?.txt")

数字范围

glob.glob("/home/ach/*[0-9]*")

字母范围

glob.glob("/home/ach/[a-c]*")

答案 7 :(得分:2)

你可能也想要一种更高级的方法(我已经实现并打包为 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

答案 8 :(得分:2)

import os

dir="/path/to/dir"
[x[0]+"/"+f for x in os.walk(dir) for f in x[2] if f.endswith(".jpg")]

这将为您提供一个jpg文件列表及其完整路径。您可以将x[0]+"/"+f替换为f仅用于文件名。您也可以用您希望的任何字符串条件替换f.endswith(".jpg")

答案 9 :(得分:1)

“path / to / images”中带有“jpg”和“png”扩展名的文件名:

import os
accepted_extensions = ["jpg", "png"]
filenames = [fn for fn in os.listdir("path/to/images") if fn.split(".")[-1] in accepted_extensions]

答案 10 :(得分:1)

您可以使用Python标准库3.4及更高版本中提供的pathlib

from pathlib import Path

files = [f for f in Path.cwd().iterdir() if f.match("145592*.jpg")]

答案 11 :(得分:1)

您可以定义图案并进行检查。在这里,我采用了开始和结束模式,并在文件名中查找它们。 FILES包含目录中所有文件的列表。

import os
PATTERN_START = "145592"
PATTERN_END = ".jpg"
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
for r,d,FILES in os.walk(CURRENT_DIR):
    for FILE in FILES:
        if PATTERN_START in FILE and PATTERN_END in FILE:
            print FILE

答案 12 :(得分:0)

str.split()怎么样?什么也没导入。

import os

image_names = [f for f in os.listdir(path) if len(f.split('.jpg')) == 2]

答案 13 :(得分:-1)

您可以将subprocess.check_ouput()用作

import subprocess

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

当然,引号之间的字符串可以是您想要在shell中执行的任何内容,并存储输出。