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)
CODE BELLOW RÉPOND À LA QUESTION DANS LE COMMENTAIRE SUIVANT
Cela a très bien fonctionné, existe-t-il un moyen de le faire si la correspondance est trouvée sur le groupe regex 1 et de le faire si la correspondance est trouvée sur le groupe regex 2, etc. – 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)
Il pourrait être possible de le faire d'une manière plus agréable, mais cela fonctionne.
Voici une alternative utilisant 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)
Étant donné que vous êtes débutant, je vous recommande d'utiliser glob
à la place d'un matcher file-walking-regex écrit rapidement.
Extraits de fonctions utilisant glob
et un file-walking-regex matcher
L'extrait ci-dessous contient deux fonctions de recherche de fichier-regex (une utilisant glob
et l'autre en utilisant un matcher file-walking-regex personnalisé). L'extrait contient également une fonction "chronomètre" pour chronométrer les deux fonctions.
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))
Comparaison des durées d'exécution des fonctions ci-dessus
En utilisant les deux fonctions ci-dessus pour trouver 5076 fichiers correspondant à la regex filename_*.csv
dans un répertoire nommé root_path
(contenant 66 948 fichiers) :
>>> 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
Le glob
méthode est beaucoup plus rapide et le code correspondant est plus court.
Pour votre cas
Pour votre cas, vous pouvez probablement utiliser quelque chose comme ce qui suit pour obtenir votre *.zip
,*.rar
et *.r01
fichiers :
files = []
for ext in ['*.zip', '*.rar', '*.r01']:
files += get_filepaths_with_glob(root_path, ext)
Je le ferais de cette façon :
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
REMARQUE :par défaut, il analysera de manière récursive tous les sous-répertoires. Si vous souhaitez analyser uniquement le répertoire en cours, vous devez spécifier explicitement glob_mask="*"