0Pricing
AI Agents · Lekcja

Przechodzenie po katalogach i wyszukiwanie plików

os.walk(), wzorce glob oraz filtrowanie plików według typu lub daty.

Przechodzenie po katalogach i wyszukiwanie plików to bezpłatna lekcja AI Agents na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej AI Agents, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs AI Agents zawiera 4 lekcji w sumie.

Dlaczego agenty potrzebują przeszukiwania katalogów

Agenty często muszą znajdować pliki spełniające określone kryteria — wszystkie pliki Pythona w bazie kodu, wszystkie pliki CSV w katalogu danych lub wszystkie najnowsze dzienniki. Python udostępnia trzy główne narzędzia: os.walk(), Path.iterdir() i Path.rglob(). Każde z nich ma inne zalety, zależnie od wymaganej głębokości wyszukiwania.

import os
from pathlib import Path

# Count all files in a directory tree
root = Path('/tmp/agent_workspace')
file_count = sum(1 for f in root.rglob('*') if f.is_file())
print(f'Found {file_count} files under {root}')

os.walk() — rekurencyjne przeszukiwanie katalogów

os.walk(root) zwraca krotkę (dirpath, dirnames, filenames) dla każdego katalogu w drzewie. Jest to klasyczne podejście Pythona do rekurencyjnego przeszukiwania katalogów, zapewniające szczegółową kontrolę nad tym, do których podkatalogów należy wejść.

import os
import tempfile

# --- demo setup: build a small project tree so the walk has something to show ---
root = tempfile.mkdtemp(prefix='project_')
os.makedirs(os.path.join(root, 'src'), exist_ok=True)
os.makedirs(os.path.join(root, '.git'), exist_ok=True)
with open(os.path.join(root, 'README.md'), 'w') as f:
    f.write('demo')
with open(os.path.join(root, 'src', 'main.py'), 'w') as f:
    f.write('print(1)')

for dirpath, dirnames, filenames in os.walk(root):
    # Skip hidden directories (like .git)
    dirnames[:] = [d for d in dirnames if not d.startswith('.')]

    print(f'In directory: {dirpath}')
    print(f'  Subdirs: {dirnames}')
    print(f'  Files: {filenames}')

    for filename in filenames:
        full_path = os.path.join(dirpath, filename)
        print(f'  File: {full_path}')

Path.iterdir() — wyświetlanie jednego poziomu

Path.iterdir() wyświetla bezpośrednią zawartość katalogu — nie przeszukuje podkatalogów rekurencyjnie. Należy go używać, gdy potrzebne są tylko bezpośrednie elementy podrzędne katalogu i nie ma potrzeby schodzenia głębiej.

from pathlib import Path

data_dir = Path('data')
data_dir.mkdir(exist_ok=True)
(data_dir / 'a.csv').write_text('x')
(data_dir / 'sub').mkdir(exist_ok=True)

for item in data_dir.iterdir():
    if item.is_file():
        print(f'FILE: {item.name} ({item.stat().st_size} bytes)')
    elif item.is_dir():
        print(f'DIR:  {item.name}/')

csv_files = [f for f in data_dir.iterdir()
             if f.is_file() and f.suffix == '.csv']
print(f'Found {len(csv_files)} CSV files')

Path.rglob() — rekurencyjne wyszukiwanie według wzorca

Path.rglob(pattern) rekurencyjnie wyszukuje wszystkie pliki pasujące do wzorca glob. Jest to najbardziej zwięzły sposób znajdowania wszystkich plików danego typu w dowolnym miejscu drzewa katalogów. ** we wzorcu glob oznacza „dowolną liczbę katalogów”.

from pathlib import Path

project = Path('/tmp/my_project')

# Find all Python files recursively
python_files = list(project.rglob('*.py'))
print(f'Found {len(python_files)} Python files:')
for f in python_files:
    print(f'  {f.relative_to(project)}')

# Find all JSON files
json_files = list(project.rglob('*.json'))

# Find files matching a name pattern
test_files = list(project.rglob('test_*.py'))
print(f'Found {len(test_files)} test files')

glob.glob() — dopasowywanie wzorców

glob.glob(pattern, recursive=True) to tradycyjny interfejs glob. Po ustawieniu recursive=True symbol wieloznaczny ** dopasowuje dowolną ścieżkę podkatalogu. Funkcja zwraca ciągi znaków, natomiast pathlib.rglob zwraca obiekty Path.

import glob

# Find all CSV files recursively
csv_files = glob.glob('data/**/*.csv', recursive=True)
print(f'Found {len(csv_files)} CSV files')
for f in csv_files:
    print(f'  {f}')

# Find all log files in a specific directory (non-recursive)
logs = glob.glob('/var/log/*.log')

# Find files matching multiple criteria
import fnmatch
all_files = glob.glob('/tmp/**/*', recursive=True)
config_files = [
    f for f in all_files
    if fnmatch.fnmatch(f, '*.yaml') or fnmatch.fnmatch(f, '*.yml')
]
print(f'Found {len(config_files)} YAML config files')

Filtrowanie według rozszerzenia pliku

Podczas przeszukiwania katalogów należy filtrować pliki według rozszerzenia za pomocą Path.suffix (które zawiera kropkę, na przykład '.py') lub sprawdzać rozszerzenie względem zbioru dozwolonych rozszerzeń. W przypadku filtrowania według wielu rozszerzeń jest to szybsze i dokładniejsze niż wzorce glob.

from pathlib import Path

directory = Path('/tmp/mixed_files')

ALLOWED_EXTENSIONS = {'.py', '.js', '.ts', '.json', '.yaml'}

# Filter by allowed extensions
code_files = [
    f for f in directory.rglob('*')
    if f.is_file() and f.suffix.lower() in ALLOWED_EXTENSIONS
]

print(f'Found {len(code_files)} code/config files')

# Group files by extension
from collections import defaultdict
by_ext = defaultdict(list)
for f in directory.rglob('*'):
    if f.is_file():
        by_ext[f.suffix].append(f)

for ext, files in sorted(by_ext.items()):
    print(f'{ext}: {len(files)} files')

Filtrowanie według rozmiaru pliku

Agenty czasami muszą znajdować pliki powyżej lub poniżej określonego progu rozmiaru — pomijać małe, puste pliki albo unikać przetwarzania ogromnych plików, które mogłyby przeciążyć pamięć. Rozmiar pliku w bajtach można uzyskać za pomocą Path.stat().st_size.

from pathlib import Path

data_dir = Path('/tmp/data')

MIN_SIZE = 1024        # 1 KB — skip empty/tiny files
MAX_SIZE = 50_000_000  # 50 MB — skip very large files

processable = []
skipped_small = []
skipped_large = []

for f in data_dir.rglob('*.json'):
    if not f.is_file():
        continue
    size = f.stat().st_size
    if size < MIN_SIZE:
        skipped_small.append(f.name)
    elif size > MAX_SIZE:
        skipped_large.append(f.name)
    else:
        processable.append(f)

print(f'Processable: {len(processable)}')
print(f'Too small: {len(skipped_small)}')
print(f'Too large: {len(skipped_large)}')

Filtrowanie według czasu modyfikacji

Agenty w potokach przyrostowych muszą przetwarzać tylko pliki, które zmieniły się od czasu ostatniego uruchomienia. Aby znaleźć ostatnio zmodyfikowane pliki, należy użyć stat().st_mtime (czasu modyfikacji w postaci znacznika czasu Unix).

from pathlib import Path
import time
import datetime

data_dir = Path('/tmp/data')

# Files modified in the last 24 hours
cutoff = time.time() - (24 * 60 * 60)

recent_files = [
    f for f in data_dir.rglob('*.log')
    if f.is_file() and f.stat().st_mtime > cutoff
]

print(f'Modified in last 24h: {len(recent_files)} files')

# Sort by modification time (newest first)
recent_files.sort(key=lambda f: f.stat().st_mtime, reverse=True)

for f in recent_files[:5]:  # top 5 most recent
    mtime = datetime.datetime.fromtimestamp(f.stat().st_mtime)
    print(f'  {f.name}: {mtime.strftime("%Y-%m-%d %H:%M:%S")}')

Pomijanie ukrytych plików i katalogów systemowych

Podczas przeszukiwania repozytoriów kodu lub katalogów użytkowników należy pomijać ukryte pliki (zaczynające się od .) oraz katalogi systemowe, takie jak .git, __pycache__, node_modules i .venv. Zawierają one tysiące plików, które w przypadku większości agentów są nieistotne.

from pathlib import Path

SKIP_DIRS = {'.git', '__pycache__', 'node_modules', '.venv',
             '.env', 'dist', 'build', '.mypy_cache'}

def iter_source_files(root, extensions):
    root = Path(root)
    for path in root.rglob('*'):
        # Skip if any parent is in SKIP_DIRS
        if any(part in SKIP_DIRS for part in path.parts):
            continue
        # Skip hidden files
        if path.name.startswith('.'):
            continue
        if path.is_file() and path.suffix in extensions:
            yield path

python_files = list(iter_source_files('/tmp/project', {'.py'}))
print(f'Found {len(python_files)} Python source files')

Tworzenie inwentarza plików

Inwentarz plików to uporządkowane podsumowanie drzewa katalogów — przydatne w przypadku agentów, które muszą zaplanować pracę przed rozpoczęciem przetwarzania. Należy zebrać nazwę, ścieżkę, rozmiar, rozszerzenie i czas modyfikacji na liście słowników, którą można serializować do formatu JSON.

from pathlib import Path
import datetime
import json

def build_inventory(root_dir, pattern='**/*'):
    root = Path(root_dir)
    inventory = []

    for f in root.glob(pattern):
        if not f.is_file():
            continue
        stat = f.stat()
        inventory.append({
            'name': f.name,
            'path': str(f.relative_to(root)),
            'extension': f.suffix,
            'size_bytes': stat.st_size,
            'modified': datetime.datetime.fromtimestamp(
                stat.st_mtime
            ).isoformat()
        })

    return sorted(inventory, key=lambda x: x['path'])

inventory = build_inventory('/tmp/data')
with open('file_inventory.json', 'w') as out:
    json.dump(inventory, out, indent=2)
print(f'Inventoried {len(inventory)} files')

Monitorowanie katalogu pod kątem zmian

Niektóre agenty muszą reagować na pojawianie się nowych plików w katalogu. Chociaż w środowisku produkcyjnym najlepiej sprawdza się pełna biblioteka do monitorowania plików, taka jak watchdog, prostym rozwiązaniem jest okresowe skanowanie katalogu i porównywanie wyników ze znanym zbiorem plików.

from pathlib import Path
import time

def watch_for_new_files(watch_dir, extension='.json', interval=5):
    watch_dir = Path(watch_dir)
    known_files = set(watch_dir.glob(f'*{extension}'))
    print(f'Watching {watch_dir} for new {extension} files...')

    while True:
        time.sleep(interval)
        current_files = set(watch_dir.glob(f'*{extension}'))
        new_files = current_files - known_files

        for f in new_files:
            print(f'New file detected: {f.name}')
            process_new_file(f)  # handle the new file

        known_files = current_files

def process_new_file(file_path):
    print(f'Processing: {file_path}')

# --- demo (one polling cycle, without the infinite while True loop) ---
import tempfile
demo_dir = Path(tempfile.mkdtemp())
known_files = set(demo_dir.glob('*.json'))
print(f'Watching {demo_dir} for new .json files...')

(demo_dir / 'result_a.json').write_text('{}', encoding='utf-8')
(demo_dir / 'result_b.json').write_text('{}', encoding='utf-8')

current_files = set(demo_dir.glob('*.json'))
new_files = current_files - known_files
for f in sorted(new_files, key=lambda p: p.name):
    print(f'New file detected: {f.name}')
    process_new_file(f)

Szybki test: rglob a iterdir

Sprawdź swoją znajomość metod przeszukiwania katalogów.

Podsumowanie przeszukiwania katalogów

Możesz teraz znaleźć każdy plik potrzebny agentowi:

  • os.walk() — pełna kontrola nad rekurencyjnym przeszukiwaniem; aby pominąć podkatalogi, modyfikuj dirnames bezpośrednio
  • Path.iterdir() — wyświetlanie jednego poziomu bezpośrednich elementów podrzędnych
  • Path.rglob('*.ext') — najbardziej przejrzyste rekurencyjne wyszukiwanie według wzorca
  • glob.glob('**/*.ext', recursive=True) — tradycyjna alternatywa zwracająca ciągi znaków
  • Filtruj według .suffix w przypadku rozszerzenia, .stat().st_size w przypadku rozmiaru i .stat().st_mtime w przypadku czasu modyfikacji
  • Zawsze pomijaj ukryte pliki i katalogi systemowe, takie jak .git i node_modules

Często zadawane pytania

Czy lekcja „Przechodzenie po katalogach i wyszukiwanie plików” jest bezpłatna?

Tak — pełny tekst „Przechodzenie po katalogach i wyszukiwanie plików” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu AI Agents, przejdź na CoddyKit PRO. Kurs AI Agents zawiera 4 lekcji w sumie.

Co nauczysz się w „Przechodzenie po katalogach i wyszukiwanie plików”?

os.walk(), wzorce glob oraz filtrowanie plików według typu lub daty. Ćwiczysz AI Agents z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć AI Agents?

Nie wymagamy żadnego doświadczenia. AI Agents w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Przechodzenie po katalogach i wyszukiwanie plików”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji AI Agents?

Tak. Każda lekcja AI Agents zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Odczyt i zapis plików w kontekście agenta
  2. Przechodzenie po katalogach i wyszukiwanie plików
  3. Obsługa formatów plików: CSV, JSON i TXT
  4. Bezpieczne operacje na plikach z obsługą błędów
← Powrót do AI Agents