0Pricing
AI Agents · บทเรียน

การไล่สำรวจไดเรกทอรีและค้นหาไฟล์

os.walk(), รูปแบบ glob และการกรองไฟล์ตามประเภทหรือวันที่

การไล่สำรวจไดเรกทอรีและค้นหาไฟล์ เป็นบทเรียน AI Agents ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Agents และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน

เหตุผลที่เอเจนต์ต้องสำรวจไดเรกทอรี

เอเจนต์มักต้องค้นหาไฟล์ที่ตรงตามเงื่อนไขบางอย่าง เช่น ไฟล์ Python ทั้งหมดในฐานโค้ด ไฟล์ CSV ทั้งหมดในไดเรกทอรีข้อมูล หรือไฟล์บันทึกล่าสุดทั้งหมด Python มีเครื่องมือหลักสามอย่าง ได้แก่ os.walk(), Path.iterdir() และ Path.rglob() แต่ละอย่างมีจุดเด่นแตกต่างกัน ขึ้นอยู่กับความลึกที่คุณต้องการค้นหา

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() — การสำรวจไดเรกทอรีแบบเรียกซ้ำ

os.walk(root) จะส่งคืนทูเพิล (dirpath, dirnames, filenames) สำหรับทุกไดเรกทอรีในโครงสร้างต้นไม้ วิธีนี้เป็นแนวทางแบบดั้งเดิมของ Python สำหรับการสำรวจแบบเรียกซ้ำ และช่วยให้คุณควบคุมได้ละเอียดว่าจะลงไปยังไดเรกทอรีย่อยใดบ้าง

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() — การแสดงรายการระดับเดียว

Path.iterdir() แสดงเนื้อหาโดยตรงของไดเรกทอรี โดยจะไม่สำรวจเข้าไปในไดเรกทอรีย่อย ให้ใช้เมื่อคุณต้องการเฉพาะรายการย่อยโดยตรงของไดเรกทอรี และต้องการหลีกเลี่ยงการลงไปยังระดับที่ลึกกว่า

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() — การค้นหาแบบโกลบซ้ำ

Path.rglob(pattern) ค้นหาไฟล์ทั้งหมดที่ตรงกับรูปแบบการค้นหาแบบโกลบโดยสำรวจแบบเรียกซ้ำ วิธีนี้เป็นวิธีที่กระชับที่สุดในการค้นหาไฟล์ทุกไฟล์ของชนิดที่กำหนดไม่ว่าจะอยู่ที่ใดในโครงสร้างไดเรกทอรี เครื่องหมาย ** ในโกลบหมายถึง «ไดเรกทอรีจำนวนเท่าใดก็ได้»

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() — การจับคู่รูปแบบ

glob.glob(pattern, recursive=True) เป็นส่วนติดต่อแบบโกลบดั้งเดิม เมื่อใช้ recursive=True อักขระตัวแทน ** จะจับคู่กับพาธไดเรกทอรีย่อยใด ๆ ก็ได้ ฟังก์ชันนี้ส่งคืนสตริง ในขณะที่ pathlib.rglob ส่งคืนวัตถุ 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')

การกรองตามนามสกุลไฟล์

ขณะสำรวจไดเรกทอรี ให้กรองไฟล์ตามนามสกุลด้วย Path.suffix (ซึ่งรวมจุดไว้ด้วย เช่น '.py') หรือเปรียบเทียบกับชุดนามสกุลที่อนุญาต วิธีนี้ทำงานได้เร็วและแม่นยำกว่ารูปแบบโกลบเมื่อจำเป็นต้องกรองหลายนามสกุล

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

การกรองตามขนาดไฟล์

บางครั้งเอเจนต์ต้องค้นหาไฟล์ที่มีขนาดสูงหรือต่ำกว่าเกณฑ์ เช่น ข้ามไฟล์ว่างขนาดเล็ก หรือหลีกเลี่ยงการประมวลผลไฟล์ขนาดใหญ่จนใช้หน่วยความจำมากเกินไป ให้ใช้ 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)}')

การกรองตามเวลาที่แก้ไข

เอเจนต์ในกระบวนการแบบเพิ่มทีละส่วนจำเป็นต้องประมวลผลเฉพาะไฟล์ที่เปลี่ยนแปลงนับจากการทำงานครั้งล่าสุดเท่านั้น ใช้ stat().st_mtime (เวลาที่แก้ไขในรูปค่าประทับเวลา 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")}')

การข้ามไฟล์ซ่อนและไดเรกทอรีระบบ

ขณะสำรวจคลังโค้ดหรือไดเรกทอรีของผู้ใช้ ให้ข้ามไฟล์ซ่อน (ที่ขึ้นต้นด้วย .) และไดเรกทอรีระบบ เช่น .git, __pycache__, node_modules และ .venv เนื้อหาเหล่านี้มีไฟล์หลายพันไฟล์ซึ่งไม่เกี่ยวข้องกับเอเจนต์ส่วนใหญ่

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

การสร้างบัญชีรายการไฟล์

บัญชีรายการไฟล์คือสรุปแบบมีโครงสร้างของโครงสร้างต้นไม้ไดเรกทอรี ซึ่งมีประโยชน์สำหรับเอเจนต์ที่ต้องวางแผนงานก่อนประมวลผล ให้รวบรวมชื่อ พาธ ขนาด นามสกุล และเวลาที่แก้ไขลงในรายการพจนานุกรมที่สามารถแปลงเป็น 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')

การเฝ้าดูไดเรกทอรีเพื่อดูการเปลี่ยนแปลง

เอเจนต์บางประเภทจำเป็นต้องตอบสนองเมื่อมีไฟล์ใหม่ปรากฏในไดเรกทอรี แม้ไลบรารีเฝ้าดูไฟล์เต็มรูปแบบอย่าง watchdog จะเหมาะที่สุดสำหรับการใช้งานจริง แต่แนวทางง่าย ๆ คือสแกนไดเรกทอรีเป็นระยะและเปรียบเทียบกับชุดไฟล์ที่ทราบอยู่แล้ว

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)

ตรวจสอบความเข้าใจ: rglob กับ iterdir

ทดสอบความเข้าใจเกี่ยวกับวิธีสำรวจไดเรกทอรี

สรุปการสำรวจไดเรกทอรี

ขณะนี้คุณสามารถค้นหาไฟล์ใด ๆ ที่เอเจนต์ต้องการได้แล้ว:

  • os.walk() — ควบคุมการสำรวจแบบเรียกซ้ำได้อย่างเต็มที่ แก้ไข dirnames โดยตรงเพื่อไม่สำรวจไดเรกทอรีย่อยบางส่วน
  • Path.iterdir() — แสดงรายการระดับเดียวของรายการย่อยโดยตรง
  • Path.rglob('*.ext') — การค้นหาแบบเรียกซ้ำตามรูปแบบที่สะอาดที่สุด
  • glob.glob('**/*.ext', recursive=True) — ทางเลือกแบบดั้งเดิมที่ส่งคืนสตริง
  • กรองตาม .suffix สำหรับนามสกุล ตาม .stat().st_size สำหรับขนาด และตาม .stat().st_mtime สำหรับเวลาที่แก้ไข
  • ข้ามไฟล์ซ่อนและไดเรกทอรีระบบ เช่น .git และ node_modules เสมอ

คำถามที่พบบ่อย

บทเรียน “การไล่สำรวจไดเรกทอรีและค้นหาไฟล์” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การไล่สำรวจไดเรกทอรีและค้นหาไฟล์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Agents ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การไล่สำรวจไดเรกทอรีและค้นหาไฟล์”

os.walk(), รูปแบบ glob และการกรองไฟล์ตามประเภทหรือวันที่ คุณปฏิบัติ AI Agents ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Agents หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Agents บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “การไล่สำรวจไดเรกทอรีและค้นหาไฟล์” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน AI Agents นี้ได้ไหม

ได้ บทเรียน AI Agents ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การอ่านและเขียนไฟล์ในบริบทของตัวแทน
  2. การไล่สำรวจไดเรกทอรีและค้นหาไฟล์
  3. การจัดการรูปแบบไฟล์: CSV, JSON และ TXT
  4. การดำเนินการกับไฟล์อย่างปลอดภัยพร้อมจัดการข้อผิดพลาด
← กลับไปที่ AI Agents