2010-08-31 5 views
20

Я пытаюсь найти все файлы .c в каталоге, используя Python.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

Изучите специальные символы регулярного выражения; dot '.' соответствует почти любому (необязательные разрывы строк). http://docs.python.org/library/re.html#regular-expression-syntax –

+1

Я думаю, что ваш regExp нуждается в небольшой модификации, что-то вроде 'code'if re.search ('. * \. c $' , f): 'code' –

ответ

31

попробуйте изменить внутреннюю петлю на что-то вроде этого

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

, но для ясности это должно быть 'results + = [каждый для каждого в os.listdir (папке), если each.endswith (' .c')]. – BeeBand

+0

@BeeBand правый, спасибо. я пропустил ваше обновление вопроса, теперь мой ответ также обновлен. – deif

+0

Мне нравится один лайнер, так что он получает очки. – BeeBand

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

+0

@BeeBand Достаточно честный – fredley

+0

Этот код работает около 3 минут, а затем возвращает мне пустой список. Просто интересно, попробовали ли вы это? – BeeBand

26

Try "Глоб":

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

+1: это именно то, для чего был разработан глобус. Использование регулярного выражения - массивный перебор. –

+0

@ Дэйв - некоторые люди, похоже, думают, что «глобус» тоже слишком переполнен (см. Комментарий @ Jive ниже). Я не знаю достаточно о внутренностях 'glob', чтобы прокомментировать это. – BeeBand

+0

'glob' также использует regex plus' os.listdir() '- плюс множество генераторов, вызовы функций, рекурсии, if/else's, os.path.split + join ... Поэтому его медленное, но простое использование, если вам нужно полный путь в любом случае. Странно: в Windows внутри posixmodule.c использует 'FileFindFirstW/NextW (" directory \\ *. * ")' Для 'os.listdir (" directory ")' :-) Так что рассмотрите 'win32api.FindFiles ('directory/*. c ')] 'в Windows для скорости. – kxr

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

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

Вы можете дать объяснение регулярному выражению '' ^. *? \. C $ "'. Будет ли '. [.]. C $' не достаточно, как предложил @Vatine? – BeeBand

+0

Я запустил ваш код, и он возвращает мне и пустой список - вы пробовали это из кучи файлов .c? Возможно, это как-то связано с именами моих файлов. Однако код Vatine работает. – BeeBand

+0

@BeeBand: (ответ на второй комментарий): I * did * test it; Я получаю все '.c' файлы в данном' каталоге'. Являются ли ваши расширения файлов верхним регистром случайно? В этом случае при компиляции регулярного выражения вам нужно будет использовать флаг 're.I'. –

0

Если заменить '.c' с '[.]c$', вы ищете файлы, которые содержат .c как последние два символа имени, а не все файлы, содержащие c, по крайней мере с одним символом перед ним.

Edit: В качестве альтернативы, матч f[-2:] с '.c', это может быть вычислительно дешевле, чем вытащив матч регулярного выражения.

+0

большой - это работает. – BeeBand

+0

Использование re или glob выигрывает приз Sledge-Hammer-to-Kill-a-Fly. –

4

ПОЦЕЛУЙ

# 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 находится в документации. Я сделал это, чтобы принять список расширений для 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 (источник, Тарг, '.config', '.bat')

0

Просто чтобы быть ясно, если вы хотите, символ точки в вашем плане поиска, вы могли бы спасся тоже:

даст вам то, что вам нужно, плюс вам нужно будет использовать что-то вроде «* [обратный слэш] .c.»:

результатов.append (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

+0

@ DimaSan Спасибо за ваше предложение. Теперь я редактировал код. –

Смежные вопросы