2010-08-31 135 views
20

我正在嘗試使用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

回答

31

嘗試改變內循環,這樣的事情

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

4
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

26

試試「水珠」:

>>> 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

1
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

0

如果您要更換'.c''[.]c$',您正在搜索包含.c作爲名稱的最後兩個字符的文件,而不是全部包含c的文件,其中至少有一個字符。

編輯:另外,比賽f[-2:]'.c',這可能是計算量比拉出一個正則表達式匹配便宜。

+0

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

+0

使用re或glob贏得大雪殺戮大獎。 – 2010-08-31 12:40:01

4

KISS

# KISS 

import os 

results = [] 

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

print results 
2

對於另一種選擇,你可以使用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')]  
1

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' )

0

只是要清楚,如果你想在你的搜索詞點字符,你可能已經逃脫它太:

會給你你需要的東西,再加上你需要使用類似「* [反斜線] .C。」:

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

2

有一個更好的解決方案,直接使用正則表達式,它是用於處理文件名模式的標準庫模塊fnmatch。 (參見glob模塊。)

寫一個輔助函數:

import fnmatch 
import os 

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

,並用它如下:

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

這個函數返回所有文件名的列表,指定的擴展住在指定目錄:

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') 
1

更改目錄到指定的路徑,這樣就可以目錄中搜索文件。如果你不改變的目錄,然後這個代碼將在您的當前目錄位置搜索文件:

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

相關問題