GNU/Linux >> Znalost Linux >  >> Linux

Jak prohledám adresáře a najdu soubory, které odpovídají regulárnímu výrazu?

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)

V NÁSLEDUJÍCÍM KOMENTÁŘE ODPOVÍDEJTE NÁSLEDUJÍCÍ OTÁZKU

To fungovalo opravdu dobře, existuje způsob, jak to udělat, pokud je nalezena shoda ve skupině regulárních výrazů 1, a provést to, pokud je nalezena shoda ve skupině regulárních výrazů 2 atd.? – 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)

Možná by to šlo udělat hezčím způsobem, ale tohle funguje.


Zde je alternativa pomocí 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)

Vzhledem k tomu, že jste začátečník, doporučuji použít glob místo rychle zapsaného nástroje pro vyhledávání regexů.

Úryvky funkcí pomocí glob a file-walking-regex matcher

Níže uvedený úryvek obsahuje dvě funkce pro vyhledávání podle regulárního výrazu souboru (jedna používá glob a druhý pomocí vlastního nástroje pro vyhledávání regexů v souborech). Úryvek také obsahuje funkci "stopky" pro měření času obou funkcí.

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

Porovnání doby běhu výše uvedených funkcí

Při použití výše uvedených dvou funkcí k nalezení 5076 souborů odpovídajících regulárnímu výrazu filename_*.csv v adresáři s názvem root_path (obsahující 66 948 souborů):

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

glob metoda je mnohem rychlejší a kód pro ni je kratší.

Pro váš případ

Pro váš případ můžete pravděpodobně použít něco jako následující, abyste získali svůj *.zip ,*.rar a *.r01 soubory:

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

Udělal bych to takto:

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

POZNÁMKA:Ve výchozím nastavení bude rekurzivně skenovat všechny podadresáře. Pokud chcete skenovat pouze aktuální adresář, měli byste explicitně zadat glob_mask="*"


Linux
  1. Jak najít a odstranit prázdné adresáře a soubory v Unixu

  2. Jak najít a odstranit prázdné adresáře a soubory v Linuxu

  3. Jak rekurzivně vypsat všechny soubory a adresáře

  1. Jak zjistit nejlepší adresáře a soubory (místo na disku) v Linuxu

  2. Jak vyhledávat a odstraňovat adresáře rekurzivně v systému Linux

  3. Najděte soubory a adresáře v Linuxu jako profík

  1. Jak najít soubory na Ubuntu?

  2. Jak hledat soubory podle velikosti a přípony?

  3. Jak hledat soubory pomocí regulárního výrazu ve skriptu linuxového shellu