Модуль fnmatch - соответствие шаблонам имен файлов UNIX.
Модуль предоставляет поддержку подстановок в стиле оболочки UNIX, которые не являются тем же самым что и регулярные выражения, описанные в модуле re.
Специальными символами являются:
Шаблон | Значение |
---|---|
* | Совпадает любое количество (включая ноль) символов |
? | Совпадает любой одиночный символ |
[foo] | Совпадает любой символ из заданной последовательности |
[!foo] | Совпадает любой символ не входящий в заданную последовательность |
fnmatch.fnmatch(filename, pattern)
Проверяет соответствие строки filename строке шаблону pattern, возвращает True в случае соответствия. Если операционная система чуствительна к регистру, то оба параметра будут приведены к нижнему или верхнему регистру перед тем как произойдет сравнение. Если необходимо сравнение учитываающее регистр, то необходимо воспользоваться fnmatchcase() .
import fnmatch, os
for file in os.listdir('.' ):
if fnmatch.fnmatch(file, '*.txt' ):
print file
fnmatch.fnmatchcase(filename, pattern)
Замечание: на самом деле преобразование регистра происходит всегда.
Следующий пример выведет на экран все имена файлов в текущей директории с расширением .txt:
Проверяет соответствие строки filename строке шаблону pattern учитывая регистр символов.
fnmatch.filter(names, pattern)
Возвращает список элементов в names которые соответствуют шаблону pattern. Это тоже самое что и [n for n in names if fnmatch(n, pattern)] , но выполняется более эффективно.
Новое в версии 2.2
fnmatch.translate(pattern)
Возвращает преобразованный в регулярное выражение шаблон pattern
Не смотря на то что речь идет об использовании имен файлов, данный механизм можно использовать шире, например:
# -*- coding: utf-8 -*-
import fnmatch
# список строк, представляющих собой какой-либо набор данных
data=['report_may',
'Report_june',
'report December',
'article_12',
'Article_54' ]
print '\n*** 1 ***'
for i in data:
print fnmatch.fnmatch(i, 'report*' ),i
print '\n*** 2 ***'
for i in data:
print fnmatch.fnmatchcase(i, 'report*' ),i
print '\n*** 3 ***'
print fnmatch.filter(data, 'art*' )
print '\n*** 4 ***'
print fnmatch.translate('[a-d]?pat*.txt' )
Результат:
data=[
for i in data:
for i in data:
*** 1 ***
True report_may
True Report_june
True report December
False article_12
False Article_54
*** 2 ***
True report_may
False Report_june
True report December
False article_12
False Article_54
*** 3 ***
['article_12', 'Article_54']
*** 4 ***
[a-d].pat.*\.txt$
True report_may
True Report_june
True report December
False article_12
False Article_54
*** 2 ***
True report_may
False Report_june
True report December
False article_12
False Article_54
*** 3 ***
['article_12', 'Article_54']
*** 4 ***
[a-d].pat.*\.txt$
Модуль glob - Расширенный вариант fnmatch
Модуль находит все совпадения имен файлов и заданого шаблона в соответствии с правилами оболочки Unix. Для использования тильды ~ и переменных окружения необходимо использовать glob.glob(pathname)
Возвращает список путей или имен файлов которые соответствуют шаблону pathname, который может быть строкой содержащей спецификацию пути. Если Pathname является путем, то он может быть как абсолютным так и относительным. Битые символьные ссылки так же включаются в результат. Например:
glob.iglob(pathname)
# -*- coding: utf-8 -*-
import glob, os
# Меняем текущую директорию
print os.chdir('C:/' )
print '\n*** 1 ***'
# Используем в шаблоне абсолютные пути
print glob.glob('C:/Windows/System32/*.exe' )
print '\n*** 2 ***'
# Используем в шаблоне относительные пути
print glob.glob('.\\Windows\\*.exe' )
print '\n*** 3 ***'
os.chdir('C:\Windows\system32' )
# Если шаблон является объектом Unicode то и результат будет такого же типа
# Не используем в шаблоне пути, поэтому будет использоваться текущая директория
print glob.glob(u'*.com' )
print '\n*** 4 ***'
# Использование символа ~
print glob.glob(os.path.expanduser('~' )+os.sep+'*.log' )
Вывод результатов сокращен:
os.chdir(
*** 1 ***
[C:/windows/system32\\accwiz.exe', 'C:/windows/system32\\actmovie.exe', ... , 'C:/windows/system32\\wupdmgr.exe', 'C:/windows/system32\\xcopy.exe']
*** 2 ***
['C:\\Windows\\ALCMTR.EXE', 'C:\\Windows\\ALCWZRD.EXE', ... , 'C:\\Windows\\winhelp.exe', 'C:\\Windows\\winhlp32.exe']
*** 3 ***
[u'chcp.com', u'command.com', ... , u'tree.com', u'win.com']
*** 4 ***
['C:\\Documents and Settings\\mer\\ntuser.dat.LOG', 'C:\\Documents and Settings\\mer\\setup.log']
[C:/windows/system32\\accwiz.exe', 'C:/windows/system32\\actmovie.exe', ... , 'C:/windows/system32\\wupdmgr.exe', 'C:/windows/system32\\xcopy.exe']
*** 2 ***
['C:\\Windows\\ALCMTR.EXE', 'C:\\Windows\\ALCWZRD.EXE', ... , 'C:\\Windows\\winhelp.exe', 'C:\\Windows\\winhlp32.exe']
*** 3 ***
[u'chcp.com', u'command.com', ... , u'tree.com', u'win.com']
*** 4 ***
['C:\\Documents and Settings\\mer\\ntuser.dat.LOG', 'C:\\Documents and Settings\\mer\\setup.log']
Возвращает итератор, который производит такие же значения как и glob() без одновременного их сохранения.
Т.о. использование iglob выгоднее в случае если нет необходимости держать в памяти весь результирующий список или когда список большого размера.
Пример:
>>> glob.glob('*.txt')
['1 (0).txt', '1 (1).txt', '1 (2).txt', '1 (3).txt', '1 (4).txt', '1 (5).txt']
>>> it=glob.iglob('*.txt')
>>> it
<generator object iglob at 0x00F498A0>
>>> it.next()
'1 (0).txt'
>>> it.next()
'1 (1).txt'
>>> it.next()
'1 (2).txt'
>>> it.next()
'1 (3).txt'
>>> it.next()
'1 (4).txt'
>>> it.next()
'1 (5).txt'
>>> it.next()
Traceback (most recent call last):
File "", line 1, in
StopIteration
>>>for item in glob.iglob('*.txt'):
...print item
...
1 (0).txt
1 (1).txt
1 (2).txt
1 (3).txt
1 (4).txt
1 (5).txt
['1 (0).txt', '1 (1).txt', '1 (2).txt', '1 (3).txt', '1 (4).txt', '1 (5).txt']
>>> it=glob.iglob('*.txt')
>>> it
<generator object iglob at 0x00F498A0>
>>> it.next()
'1 (0).txt'
>>> it.next()
'1 (1).txt'
>>> it.next()
'1 (2).txt'
>>> it.next()
'1 (3).txt'
>>> it.next()
'1 (4).txt'
>>> it.next()
'1 (5).txt'
>>> it.next()
Traceback (most recent call last):
File "
StopIteration
>>>for item in glob.iglob('*.txt'):
...print item
...
1 (0).txt
1 (1).txt
1 (2).txt
1 (3).txt
1 (4).txt
1 (5).txt
как сделать, чтобы glob.glob нашел одновременно несколько масок, например *.gif, *.png, *.jpg ???
ОтветитьУдалитьНужно применять регулярные выражения. Даже если написать так: '*.[gpj][inp][fg]' , то под шаблон попадут нежелательные файлы. например *.gpg
ОтветитьУдалитьЕсли не хочется использовать регулярки, то можно и средствами Питона все сделать:
[x for x in filenames if any([x.endswith(y) for y in ('jpg', 'gif', 'png')])]
а если я нашла файлы, соответствующие шаблону, но они сохранились в список и представляют из себя строки, а мне нужно их прочесть и изменить их содержимое. как это сделать?
УдалитьПредположим что вы получили искомый список spisok. Далее в цикле проходите по этому списку, открываете файл с нужным именем на его изменение(!!) и проводите все необходимые операции.
Удалитьfor filename in spisok:
with open(filename, 'r+') as f:
# здесь вы изменяете свой файл методом f.write()
А вообще читайте книги по python для того что бы его изучить и понимать что вы делаете. Например автор Лутц