import os
import re
rootdir = "/mnt/externa/Torrents/completed"
regex = re.compile('(.*zip$)|(.*rar$)|(.*r01$)')
for root, dirs, files in os.walk(rootdir):
for file in files:
if regex.match(file):
print(file)
KODE DI BAWAH JAWABAN PERTANYAAN DI KOMENTAR BERIKUT
Itu bekerja dengan sangat baik, apakah ada cara untuk melakukan ini jika kecocokan ditemukan pada grup regex 1 dan lakukan ini jika kecocokan ditemukan pada grup regex 2 dll? – nillenilsson
import os
import re
regex = re.compile('(.*zip$)|(.*rar$)|(.*r01$)')
rx = '(.*zip$)|(.*rar$)|(.*r01$)'
for root, dirs, files in os.walk("../Documents"):
for file in files:
res = re.match(rx, file)
if res:
if res.group(1):
print("ZIP",file)
if res.group(2):
print("RAR",file)
if res.group(3):
print("R01",file)
Dimungkinkan untuk melakukan ini dengan cara yang lebih baik, tetapi ini berhasil.
Berikut alternatif menggunakan glob
.
from pathlib import Path
rootdir = "/mnt/externa/Torrents/completed"
for extension in 'zip rar r01'.split():
for path in Path(rootdir).glob('*.' + extension):
print("match: " + path)
Mengingat Anda seorang pemula, saya akan merekomendasikan menggunakan glob
sebagai pengganti file-walking-regex matcher yang ditulis dengan cepat.
Snippet fungsi menggunakan glob
dan file-walking-regex matcher
Cuplikan di bawah berisi dua fungsi pencarian file-regex (satu menggunakan glob
dan yang lainnya menggunakan pencocokan file-berjalan-regex khusus). Cuplikan juga berisi fungsi "stopwatch" untuk menghitung waktu kedua fungsi tersebut.
import os
import sys
from datetime import timedelta
from timeit import time
import os
import re
import glob
def stopwatch(method):
def timed(*args, **kw):
ts = time.perf_counter()
result = method(*args, **kw)
te = time.perf_counter()
duration = timedelta(seconds=te - ts)
print(f"{method.__name__}: {duration}")
return result
return timed
@stopwatch
def get_filepaths_with_oswalk(root_path: str, file_regex: str):
files_paths = []
pattern = re.compile(file_regex)
for root, directories, files in os.walk(root_path):
for file in files:
if pattern.match(file):
files_paths.append(os.path.join(root, file))
return files_paths
@stopwatch
def get_filepaths_with_glob(root_path: str, file_regex: str):
return glob.glob(os.path.join(root_path, file_regex))
Membandingkan runtime dari fungsi di atas
Saat menggunakan dua fungsi di atas untuk menemukan 5076 file yang cocok dengan regex filename_*.csv
dalam direktori bernama root_path
(berisi 66.948 file):
>>> glob_files = get_filepaths_with_glob(root_path, 'filename_*.csv')
get_filepaths_with_glob: 0:00:00.176400
>>> oswalk_files = get_filepaths_with_oswalk(root_path,'filename_(.*).csv')
get_filepaths_with_oswalk: 0:03:29.385379
glob
metode jauh lebih cepat dan kode untuk itu lebih pendek.
Untuk kasus Anda
Untuk kasus Anda, Anda mungkin dapat menggunakan sesuatu seperti berikut untuk mendapatkan *.zip
Anda ,*.rar
dan *.r01
file:
files = []
for ext in ['*.zip', '*.rar', '*.r01']:
files += get_filepaths_with_glob(root_path, ext)
Saya akan melakukannya dengan cara ini:
import re
from pathlib import Path
def glob_re(path, regex="", glob_mask="**/*", inverse=False):
p = Path(path)
if inverse:
res = [str(f) for f in p.glob(glob_mask) if not re.search(regex, str(f))]
else:
res = [str(f) for f in p.glob(glob_mask) if re.search(regex, str(f))]
return res
CATATAN:secara default ini akan memindai semua subdirektori secara rekursif. Jika Anda hanya ingin memindai direktori saat ini maka Anda harus secara eksplisit menentukan glob_mask="*"