개요
이 글에서는 파이썬(Python)으로 유닉스(UNIX) 셸 스타일의 패턴 매칭 기법을 활용하는 방법을 알아봅니다. 이를 위해 파이썬 표준 라이브러리에서 제공하는 fnmatch 모듈을 사용합니다. 이 모듈은 파일 이름과 패턴을 비교하여 일치 여부에 따라 True 또는 False를 반환합니다.
사용하려면 먼저 표준 라이브러리인 fnmatch 모듈을 임포트해야 합니다.
import fnmatch
유닉스 터미널에는 패턴을 매칭할 때 사용하는 다양한 와일드카드가 있습니다.
- '*'(애스터리스크): 모든 문자열과 일치합니다.
- '?'(물음표): 단일 문자 하나와 일치합니다.
- [seq]: 시퀀스에 포함된 문자들과 일치합니다.
- [!seq]: 시퀀스에 포함되지 않은 문자들과 일치합니다.
만약 애스터리스크(*)나 물음표(?)를 일반 문자로 검색하고 싶다면 [*] 또는 [?]처럼 대괄호 안에 넣어 사용해야 합니다.
fnmatch() 메서드
fnmatch() 메서드는 파일 이름(filename)과 패턴(pattern) 두 개의 인자를 받습니다. 이 함수는 주어진 파일 이름이 지정된 패턴과 일치하는지 확인하는 데 사용됩니다. 운영체제가 대소문자를 구분하는 경우, 매칭 전에 매개변수가 대문자 또는 소문자로 정규화됩니다. 참고로 대소문자를 엄격하게 구분하여 비교하고 싶다면 fnmatchcase() 함수를 사용하면 됩니다.
예제 코드
import fnmatch
import os
file_pattern = 'test_f*'
files = os.listdir('./unix_files')
for filename in files:
print('File: {}\t: {}'.format(filename, fnmatch.fnmatch(filename, file_pattern)))
실행 결과
$ python3 310.UNIX_filename.py
File: test_file5.txt : True
File: test_file2.png : True
File: test_file1.txt : True
File: another_file.txt : False
File: TEST_FILE4.txt : False
File: abc.txt : False
File: test_file3.txt : True
$
filter() 메서드
filter() 메서드 역시 두 개의 매개변수를 받습니다. 첫 번째는 파일 이름 목록(names), 두 번째는 패턴입니다. 이 메서드는 전체 파일 이름 목록 중에서 패턴과 일치하는 파일 이름들만 골라 리스트 형태로 반환합니다.
예제 코드
import fnmatch
import os
file_pattern = 'test_f*'
files = os.listdir('./unix_files')
match_file = fnmatch.filter(files, file_pattern)
print('All files:' + str(files))
print('\nMatched files:' + str(match_file))
실행 결과
$ python3 310.UNIX_filename.py
All files:['test_file5.txt', 'test_file2.png', 'test_file1.txt', 'another_file.txt', 'TEST_FILE4.txt', 'abc.txt', 'test_file3.txt']
Matched files:['test_file5.txt', 'test_file2.png', 'test_file1.txt', 'test_file3.txt']
$
translate() 메서드
translate() 메서드는 하나의 매개변수, 즉 패턴을 받습니다. 이 함수는 셸 스타일 패턴을 파이썬 정규 표현식(regular expression)으로 변환해 주므로, re 모듈과 함께 사용하여 더 복잡한 매칭 작업에 활용할 수 있습니다.
예제 코드
import fnmatch, re
file_pattern = 'test_f*.txt'
unix_regex = fnmatch.translate(file_pattern)
regex_object = re.compile(unix_regex)
print('Regular Expression:' + str(unix_regex))
print('Match Object:' + str(regex_object.match('test_file_abcd123.txt')))
실행 결과
$ python3 310.UNIX_filename.py
Regular Expression:(?s:test_f.*\.txt)\Z
Match Object:<_sre.SRE_Match object; span=(0, 21), match='test_file_abcd123.txt'>
$