fnmatch — 유닉스 파일명 패턴 매칭

fnmatch — 유닉스 파일명 패턴 매칭

셸 스타일의 와일드카드를 써서 파일명이 특정 패턴에 맞는지 확인하고 싶을 때 쓰는 모듈이에요. 정규 표현식(그건 re 모듈에서 다루죠)과는 달라요. 셸 스타일 와일드카드에서 쓰는 특수 문자는 이렇게 돼요.

패턴 의미
* 모든 것과 매칭
? 임의의 한 문자와 매칭
[seq] seq 안의 어떤 문자와도 매칭
[!seq] seq에 없는 어떤 문자와 매칭

문자 그대로 매칭하고 싶으면 메타 문자를 대괄호로 감싸면 돼요. 예를 들어 '[?]''?' 문자를 매칭해요.

한 가지 알아둘 점이 있는데, 파일 구분자(유닉스의 '/')는 이 모듈에서 특별 취급되지 않아요. 경로명 확장은 glob 모듈을 참고하세요(globfilter()를 써서 경로명 세그먼트를 매칭해요). 마찬가지로 점으로 시작하는 파일명도 여기선 특별하지 않아서, *? 패턴에 매칭돼요.

출처: Python 표준 라이브러리

본문

별도로 말하지 않는 한, "파일명 문자열"과 "패턴 문자열"은 str 또는 ISO-8859-1 인코딩된 bytes 객체를 가리켜요. 아래 문서화한 함수들은 bytes 패턴과 str 파일명을 섞어 쓸 수 없고, 그 반대도 마찬가지라는 점을 기억해 두세요.

마지막으로, 아래 함수들(fnmatch(), fnmatchcase(), filter(), filterfalse())은 maxsize 32768의 @functools.lru_cache 로 컴파일된 (타이핑된) 정규식 패턴을 캐시해요.

fnmatch.fnmatch(name, pat)

파일명 문자열 name이 패턴 문자열 pat에 맞는지 검사해서 True 또는 False를 돌려줘요. 두 매개변수는 os.path.normcase()로 대소문자를 정규화해요. 운영체제 표준과 상관없이 대소문자를 구분해서 비교하고 싶다면 fnmatchcase()를 쓰면 돼요.

이 예제는 현재 디렉터리에서 확장자가 .txt인 모든 파일명을 출력해요.

import fnmatch
import os

for file in os.listdir('.'):
    if fnmatch.fnmatch(file, '*.txt'):
        print(file)

fnmatch.fnmatchcase(name, pat)

파일명 문자열 name이 패턴 문자열 pat에 맞는지 검사해서 True 또는 False를 돌려줘요. 비교는 대소문자를 구분하고 os.path.normcase()를 적용하지 않아요.

fnmatch.filter(names, pat)

파일명 문자열의 이터러블 names 중에서 패턴 문자열 pat에 맞는 요소들로 리스트를 만들어요. [n for n in names if fnmatch(n, pat)]와 같지만 더 효율적으로 구현돼 있어요.

fnmatch.filterfalse(names, pat)

파일명 문자열의 이터러블 names 중에서 패턴 문자열 pat맞지 않는 요소들로 리스트를 만들어요. [n for n in names if not fnmatch(n, pat)]와 같지만 더 효율적으로 구현돼 있어요.

버전 3.14에 추가됨.

fnmatch.translate(pat)

셸 스타일 패턴 patre.match()와 함께 쓸 수 있게 정규 표현식으로 변환해서 돌려줘요. 패턴은 str이어야 해요.

예제를 볼게요.

>>> import fnmatch, re
>>>
>>> regex = fnmatch.translate('*.txt')
>>> regex
'(?s:.*\\.txt)\\Z'
>>> reobj = re.compile(regex)
>>> reobj.match('foobar.txt')
<re.Match object; span=(0, 10), match='foobar.txt'>

더 알아보기

  • glob 모듈 — 유닉스 셸 스타일 경로명 확장.