GNU/Linux >> Tutoriels Linux >  >> Linux

Comment puis-je rechercher des répertoires et trouver des fichiers qui correspondent à regex ?

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="*"


Linux
  1. Comment rechercher des fichiers par taille et extension ?

  2. Comment rechercher et supprimer des répertoires et des fichiers vides sous Unix

  3. Comment lister récursivement tous les fichiers et répertoires

  4. Comment rechercher des fichiers à l'aide de regex dans le script shell Linux

  5. Comment trouver des fichiers qui ne contiennent pas une chaîne de recherche donnée

Comment renommer des fichiers et des répertoires sous Linux

Comment exclure des fichiers et des répertoires avec Rsync

Comment compresser des fichiers et des répertoires sous Linux

Comment synchroniser des fichiers et des répertoires à l'aide de Zaloha.sh

Trouvez facilement des fichiers et des répertoires sur Linux

Comment effectuer une recherche Grep sur tous les fichiers et dans tous les répertoires