GNU/Linux >> Linux Esercitazione >  >> Linux

Come posso cercare nelle directory e trovare i file che corrispondono a 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)

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


Linux
  1. Come scoprire le directory e i file principali (spazio su disco) in Linux

  2. Come elencare in modo ricorsivo tutti i file e le directory

  3. Come cercare i file usando regex nello script della shell linux

  4. Come trovare i file che non contengono una determinata stringa di ricerca

  5. Come trovo tutti i file e le directory scrivibili da un utente specifico?

Come rinominare file e directory in Linux

Come escludere file e directory con Rsync

Come comprimere file e directory in Linux

Come sincronizzare file e directory utilizzando Zaloha.sh

Trova facilmente file e directory su Linux

Come eseguire la ricerca Grep su tutti i file e in tutte le directory