GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie durchsuche ich Verzeichnisse und finde Dateien, die mit Regex übereinstimmen?

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 UNTEN BEANTWORTET DIE FRAGE IM FOLGENDEN KOMMENTAR

Das hat wirklich gut funktioniert, gibt es eine Möglichkeit, dies zu tun, wenn eine Übereinstimmung in der Regex-Gruppe 1 gefunden wird, und dies zu tun, wenn eine Übereinstimmung in der Regex-Gruppe 2 usw. gefunden wird? – 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)

Es könnte möglich sein, dies auf eine schönere Weise zu tun, aber das funktioniert.


Hier ist eine Alternative mit 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)

Da Sie ein Anfänger sind, würde ich die Verwendung von glob empfehlen anstelle eines schnell geschriebenen File-Walking-Regex-Matchers.

Schnipsel von Funktionen mit glob und ein file-walking-regex matcher

Das folgende Snippet enthält zwei Datei-Regex-Suchfunktionen (eine mit glob und der andere mit einem benutzerdefinierten File-Walking-Regex-Matcher). Das Snippet enthält auch eine "Stoppuhr"-Funktion, um die beiden Funktionen zu timen.

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))

Vergleich der Laufzeiten der oben genannten Funktionen

Bei Verwendung der beiden obigen Funktionen, um 5076-Dateien zu finden, die mit dem Regex filename_*.csv übereinstimmen in einem Verzeichnis namens root_path (enthält 66.948 Dateien):

>>> 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

Die glob -Methode ist viel schneller und der Code dafür ist kürzer.

Für Ihren Fall

Für Ihren Fall können Sie wahrscheinlich so etwas wie das Folgende verwenden, um Ihren *.zip zu erhalten ,*.rar und *.r01 Dateien:

files = []
for ext in ['*.zip', '*.rar', '*.r01']:
    files += get_filepaths_with_glob(root_path, ext) 

Ich würde es so machen:

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

HINWEIS:Standardmäßig werden alle Unterverzeichnisse rekursiv gescannt. Wenn Sie nur das aktuelle Verzeichnis scannen möchten, sollten Sie explizit glob_mask="*" angeben


Linux
  1. So finden Sie die wichtigsten Verzeichnisse und Dateien (Festplattenspeicherplatz) in Linux heraus

  2. So suchen und entfernen Sie Verzeichnisse rekursiv unter Linux

  3. So finden und löschen Sie leere Verzeichnisse und Dateien in Linux

  4. So suchen Sie nach Dateien mit Regex im Linux-Shell-Skript

  5. Wie finde ich alle Dateien und Verzeichnisse, die von einem bestimmten Benutzer beschreibbar sind?

So benennen Sie Dateien und Verzeichnisse in Linux um

So schließen Sie Dateien und Verzeichnisse mit Rsync aus

So komprimieren Sie Dateien und Verzeichnisse unter Linux

So synchronisieren Sie Dateien und Verzeichnisse mit Zaloha.sh

Finden Sie Dateien und Verzeichnisse unter Linux ganz einfach

So führen Sie eine Grep-Suche für alle Dateien und in allen Verzeichnissen durch