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)
IL CODICE SOTTO RISPONDE ALLA DOMANDA NEL SEGUENTE COMMENTO
Ha funzionato molto bene, c'è un modo per farlo se la corrispondenza viene trovata sul gruppo regex 1 e farlo se la corrispondenza viene trovata sul gruppo regex 2 ecc.? – 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)
Potrebbe essere possibile farlo in un modo migliore, ma funziona.
Ecco un'alternativa usando 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)
Dato che sei un principiante, ti consiglio di usare glob
al posto di un matcher file-walking-regex scritto velocemente.
Frammenti di funzioni che utilizzano glob
e un file-walking-regex matcher
Lo snippet seguente contiene due funzioni di ricerca file-regex (una che utilizza glob
e l'altro utilizzando un matcher file-walking-regex personalizzato). Lo snippet contiene anche una funzione "cronometro" per cronometrare le due funzioni.
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))
Confronto dei tempi di esecuzione delle funzioni di cui sopra
Usando le due funzioni precedenti per trovare 5076 file che corrispondono alla regex filename_*.csv
in una directory chiamata root_path
(contenente 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
Il glob
metodo è molto più veloce e il codice per esso è più breve.
Per il tuo caso
Nel tuo caso, probabilmente puoi usare qualcosa di simile al seguente per ottenere il tuo *.zip
,*.rar
e *.r01
file:
files = []
for ext in ['*.zip', '*.rar', '*.r01']:
files += get_filepaths_with_glob(root_path, ext)
Lo farei in questo modo:
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
NOTA:per impostazione predefinita, eseguirà la scansione ricorsiva di tutte le sottodirectory. Se vuoi scansionare solo la directory corrente allora devi specificare esplicitamente glob_mask="*"