Python:如何查找具有特定扩展名的所有文件?

问题描述:

我正在尝试使用Python在目录中找到所有.c文件。Python:如何查找具有特定扩展名的所有文件?

我写了这个,但它只是返回所有文件 - 不仅仅是.c文件。

import os 
import re 

results = [] 

for folder in gamefolders: 
    for f in os.listdir(folder): 
     if re.search('.c', f): 
      results += [f] 

print results 

我怎样才能得到.c文件?

+1

学习正则表达式的特殊字符;点'。'几乎匹配任何东西(换行符可选)。 http://docs.python.org/library/re.html#regular-expression-syntax – 2010-08-31 13:39:20

+1

我认为你的regExp需要稍作修改,例如 'code'if re.search('。* \。c $' ,f):'code' – 2012-11-15 02:41:30

尝试改变内循环,这样的事情

results += [each for each in os.listdir(folder) if each.endswith('.c')] 
+1

工作 - 但为了清楚起见,它应该是'结果+ = [如果each.endswith('.c')]在os.listdir(文件夹)中的每一个。 – BeeBand 2010-08-31 11:23:30

+0

@BeeBand对,谢谢。我错过了你的问题更新,现在我的答案也更新了。 – deif 2010-08-31 11:30:02

+0

我喜欢一个班轮,所以这个获得积分。 – BeeBand 2010-08-31 15:50:04

for _,_,filenames in os.walk(folder): 
    for file in filenames: 
     fileExt=os.path.splitext(file)[-1] 
     if fileExt == '.c': 
      results.append(file) 
+0

我想避免'os.walk',因为它似乎很慢。 – BeeBand 2010-08-31 11:28:02

+0

@BeeBand不够公平 – fredley 2010-08-31 11:30:31

+0

此代码运行约3分钟,然后返回一个空列表。只是想知道你是否尝试过? – BeeBand 2010-08-31 11:32:13

试试“水珠”:

>>> import glob 
>>> glob.glob('./[0-9].*') 
['./1.gif', './2.txt'] 
>>> glob.glob('*.gif') 
['1.gif', 'card.gif'] 
>>> glob.glob('?.gif') 
['1.gif'] 
+5

+1:这正是glob设计的目的。使用正则表达式是巨大的矫枉过正。 – 2010-08-31 12:53:14

+0

@Dave - 有些人似乎认为'glob'也有点矫枉过正(请参阅下面的@Jive的评论)。我对“glob”的内部知识不够充分,无法评论。 – BeeBand 2010-08-31 15:53:15

+0

'glob'也使用正则表达式加上'os.listdir()' - 加上许多生成器,函数调用,递归,if/else's,os.path.split + join ...所以它的缓慢但简单的用法,如果你需要无论如何,完整的路径。奇怪:在Windows内部,posixmodule.c使用'FileFindFirstW/NextW(“directory \\ *。*”)'作为'os.listdir(“directory”)':-)所以考虑'win32api.FindFiles('directory/*。 c')]'在Windows上提速。 – kxr 2016-03-01 07:24:18

import os, re 
cfile = re.compile("^.*?\.c$") 
results = [] 

for name in os.listdir(directory): 
    if cfile.match(name): 
     results.append(name) 
+0

你能给出正则表达式的解释吗?“^。*?\。c $”'。 @Vatine建议''[。]。c $'不够用吗? – BeeBand 2010-08-31 11:25:30

+0

我跑你的代码,它返回我和空列表 - 你试过这一堆的.c文件?也许这与我的文件名称有关。 @ Vatine的代码可以工作。 – BeeBand 2010-08-31 11:34:47

+0

@BeeBand :(对第二个评论的回应):我*测试了它;我正在获取给定'目录'中的所有'.c'文件。您的文件扩展名是否大写?在这种情况下,编译正则表达式时需要使用're.I'标志。 – 2010-08-31 11:47:22

如果您要更换'.c''[.]c$',您正在搜索包含.c作为名称的最后两个字符的文件,而不是全部包含c的文件,其中至少有一个字符。

编辑:另外,比赛f[-2:]'.c',这可能是计算量比拉出一个正则表达式匹配便宜。

+0

伟大 - 那工作。 – BeeBand 2010-08-31 11:23:53

+0

使用re或glob赢得大雪杀戮大奖。 – 2010-08-31 12:40:01

KISS

# KISS 

import os 

results = [] 

for folder in gamefolders: 
    for f in os.listdir(folder): 
     if f.endswith('.c'): 
      results.append(f) 

print results 

对于另一种选择,你可以使用fnmatch

import fnmatch 
import os 

results = [] 
for root, dirs, files in os.walk(path) 
    for _file in files: 
     if fnmatch.fnmatch(_file, '*.c'): 
      results.append(os.path.join(root, _file)) 

print results 

或与列表理解:

for root, dirs, files in os.walk(path) 
    [results.append(os.path.join(root, _file))\ 
     for _file in files if \ 
      fnmatch.fnmatch(_file, '*.c')] 

或使用滤光器:

for root, dirs, files in os.walk(path): 
    [results.append(os.path.join(root, _file))\ 
     for _file in fnmatch.filter(files, '*.c')]  

shutil.copytree的实施是在文档。我对它进行了mfdified,以列出INCLUDE的扩展名。

def my_copytree(src, dst, symlinks=False, *extentions): 
    """ I modified the 2.7 implementation of shutils.copytree 
    to take a list of extentions to INCLUDE, instead of an ignore list. 
    """ 
    names = os.listdir(src) 
    os.makedirs(dst) 
    errors = [] 
    for name in names: 
     srcname = os.path.join(src, name) 
     dstname = os.path.join(dst, name) 
     try: 
      if symlinks and os.path.islink(srcname): 
       linkto = os.readlink(srcname) 
       os.symlink(linkto, dstname) 
      elif os.path.isdir(srcname): 
       my_copytree(srcname, dstname, symlinks, *extentions) 
      else: 
       ext = os.path.splitext(srcname)[1] 
       if not ext in extentions: 
        # skip the file 
        continue 
       copy2(srcname, dstname) 
      # XXX What about devices, sockets etc.? 
     except (IOError, os.error), why: 
      errors.append((srcname, dstname, str(why))) 
     # catch the Error from the recursive copytree so that we can 
     # continue with other files 
     except Error, err: 
      errors.extend(err.args[0]) 
    try: 
     copystat(src, dst) 
    # except WindowsError: # cant copy file access times on Windows 
    #  pass 
    except OSError, why: 
     errors.extend((src, dst, str(why))) 
    if errors: 
     raise Error(errors) 

用途:例如,仅复制的.config和.BAT文件....

my_copytree(源,TARG, '的.config', '.BAT' )

只是要清楚,如果你想在你的搜索词点字符,你可能已经逃脱它太:

会给你你需要的东西,再加上你需要使用类似“* [反斜线] .C。”:

结果。附加(f),而不是你已经列出的结果+ = [f]

有一个更好的解决方案,直接使用正则表达式,它是用于处理文件名模式的标准库模块fnmatch。 (参见glob模块。)

写一个辅助函数:

import fnmatch 
import os 

def listdir(dirname, pattern="*"): 
    return fnmatch.filter(os.listdir(dirname), pattern) 

,并用它如下:

result = listdir("./sources", "*.c") 

这个函数返回所有文件名的列表,指定的扩展住在指定目录:

import os 

def listFiles(path, extension): 
    return [f for f in os.listdir(path) if f.endswith(extension)] 

print listFiles('/Path/to/directory/with/files', '.txt') 

如果你想列出所有的在某个目录指定的扩展及其子目录中的文件,你可以这样做:

import os 

def filterFiles(path, extension): 
    return [file for root, dirs, files in os.walk(path) for file in files if file.endswith(extension)] 

print filterFiles('/Path/to/directory/with/files', '.txt') 

更改目录到指定的路径,这样就可以目录中搜索文件。如果你不改变的目录,然后这个代码将在您的当前目录位置搜索文件:

import os #importing os library 
import glob #importing glob library 

path=raw_input() #input from the user 
os.chdir(path) 

filedata=glob.glob('*.c') #all files with .c extenstions stores in filedata. 
print filedata 
+2

虽然这段代码可以解决这个问题,但[包括解释](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers)确实有帮助以提高您的帖子的质量。请记住,您将来会为读者回答问题,而这些人可能不知道您的代码建议的原因。 – DimaSan 2017-03-15 11:23:09

+0

@DimaSan感谢您的建议。现在我编辑了代码。 – 2017-03-16 10:25:41