0Pricing
AI Agents · Aula

Percurso de diretórios e descoberta de arquivos

os.walk(), padrões glob e filtragem de arquivos por tipo ou data.

Percurso de diretórios e descoberta de arquivos é uma aula grátis de AI Agents no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de AI Agents, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de AI Agents inclui 4 aulas no total.

Por que os agentes precisam percorrer diretórios

Os agentes frequentemente precisam encontrar arquivos que correspondam a determinados critérios — todos os arquivos Python em uma base de código, todos os arquivos CSV em um diretório de dados ou todos os registros recentes. O Python oferece três ferramentas principais: os.walk(), Path.iterdir() e Path.rglob(). Cada uma tem vantagens diferentes, dependendo da profundidade da pesquisa necessária.

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() — Percurso recursivo de diretórios

os.walk(root) produz uma tupla de (dirpath, dirnames, filenames) para cada diretório da árvore. É a abordagem clássica do Python para percorrer diretórios recursivamente e oferece controle detalhado sobre quais subdiretórios devem ser percorridos.

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() — Listagem de um único nível

Path.iterdir() lista o conteúdo imediato de um diretório — ele não percorre os subdiretórios. Use-o quando precisar apenas dos filhos diretos de um diretório e quiser evitar uma busca mais profunda.

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() — Busca glob recursiva

Path.rglob(pattern) encontra recursivamente todos os arquivos que correspondem a um padrão glob. É a maneira mais concisa de encontrar todos os arquivos de determinado tipo em qualquer ponto de uma árvore de diretórios. O ** em glob significa “qualquer número de diretórios”.

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() — Correspondência de padrões

glob.glob(pattern, recursive=True) é a interface tradicional de glob. Com recursive=True, o curinga ** corresponde ao caminho de qualquer subdiretório. Ela retorna cadeias de caracteres, enquanto pathlib.rglob retorna objetos 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')

Filtrando por extensão de arquivo

Ao percorrer diretórios, filtre os arquivos pela extensão usando Path.suffix (que inclui o ponto, por exemplo, '.py') ou verificando cada uma contra um conjunto de extensões permitidas. Isso é mais rápido e preciso que usar padrões glob para filtrar várias extensões.

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

Filtrando por tamanho de arquivo

Às vezes, os agentes precisam encontrar arquivos acima ou abaixo de um limite de tamanho — ignorar arquivos vazios muito pequenos ou evitar processar arquivos enormes que sobrecarregariam a memória. Use Path.stat().st_size para obter o tamanho do arquivo em bytes.

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

Filtrando pelo horário de modificação

Os agentes em fluxos de processamento incrementais só precisam processar os arquivos que foram alterados desde a última execução. Use stat().st_mtime (o horário de modificação como um carimbo de data e hora Unix) para encontrar arquivos modificados recentemente.

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")}')

Ignorando arquivos ocultos e diretórios do sistema

Ao percorrer repositórios de código ou diretórios de usuários, ignore arquivos ocultos (que começam com .) e diretórios do sistema, como .git, __pycache__, node_modules e .venv. Eles contêm milhares de arquivos irrelevantes para a maioria dos agentes.

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

Criando um inventário de arquivos

Um inventário de arquivos é um resumo estruturado de uma árvore de diretórios — útil para agentes que precisam planejar o trabalho antes de processá-lo. Reúna nome, caminho, tamanho, extensão e horário de modificação em uma lista de dicionários que possa ser serializada em 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')

Monitorando um diretório em busca de alterações

Alguns agentes precisam reagir ao aparecimento de novos arquivos em um diretório. Embora uma biblioteca completa de monitoramento de arquivos, como watchdog, seja melhor para produção, uma abordagem simples é examinar o diretório periodicamente e comparar o resultado com um conjunto conhecido de arquivos.

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)

Verificação rápida: rglob vs iterdir

Teste sua compreensão dos métodos de percurso de diretórios.

Recapitulação do percurso de diretórios

Agora você consegue encontrar qualquer arquivo de que seu agente precise:

  • os.walk() — controle total sobre o percurso recursivo; modifique dirnames diretamente para podar subdiretórios
  • Path.iterdir() — listagem de um único nível com os filhos imediatos
  • Path.rglob('*.ext') — busca recursiva por padrão, de forma mais limpa
  • glob.glob('**/*.ext', recursive=True) — alternativa tradicional que retorna cadeias de caracteres
  • Filtre por .suffix para obter a extensão, .stat().st_size para o tamanho e .stat().st_mtime para o horário de modificação
  • Sempre ignore arquivos ocultos e diretórios do sistema, como .git e node_modules

Perguntas Frequentes

A aula “Percurso de diretórios e descoberta de arquivos” é grátis?

Sim — o texto completo de “Percurso de diretórios e descoberta de arquivos” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de AI Agents, atualize para CoddyKit PRO. O curso de AI Agents inclui 4 aulas no total.

O que vou aprender em “Percurso de diretórios e descoberta de arquivos”?

os.walk(), padrões glob e filtragem de arquivos por tipo ou data. Você pratica AI Agents com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar AI Agents?

Nenhuma experiência prévia é necessária. AI Agents no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “Percurso de diretórios e descoberta de arquivos”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de AI Agents?

Sim. Cada aula de AI Agents inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Lendo e escrevendo arquivos no contexto de agentes
  2. Percurso de diretórios e descoberta de arquivos
  3. Tratamento de formatos de arquivo: CSV, JSON e TXT
  4. Operações seguras com arquivos e tratamento de erros
← Voltar para AI Agents