Command Line cho Developer · Part 3 - Search Code with rg, find & fd
Tìm kiếm codebase như senior: rg cho nội dung, find/fd cho file, glob/exclude, context lines, file list, null separator và recipe tìm config/TODO/symbol.
Đây là Phần 3. Developer sống trong codebase lớn sẽ hỏi cùng một nhóm câu hỏi:
- Hàm này được gọi ở đâu?
- Config này nằm file nào?
- Có bao nhiêu TODO còn lại?
- Tên env var này xuất hiện ở đâu?
- File nào mới sửa gần đây?
Editor có search tốt, nhưng terminal search giúp bạn ghép với pipe, script, CI và automation.
Dùng rg trước
rg là ripgrep, công cụ search rất nhanh và mặc định hợp với codebase: nó tôn trọng .gitignore, bỏ qua thư mục nặng, và in output dễ đọc.
rg "useEffect"
rg "process.env"
rg "TODO"
Search không phân biệt hoa thường:
rg -i "authorization"
In số dòng:
rg -n "fetch\\("
Chỉ in tên file match:
rg -l "getServerSideProps"
Đếm match theo file:
rg -c "TODO"
Context lines: đọc quanh match
Một dòng match thường chưa đủ. Thêm context:
rg -C 3 "throw new Error"
rg -A 5 "function parse"
rg -B 5 "return null"
| Flag | Nghĩa |
|---|---|
-C 3 | 3 dòng trước và sau |
-A 5 | 5 dòng sau |
-B 5 | 5 dòng trước |
Khi review code bằng terminal, rg -C thường nhanh hơn mở từng file.
Glob và exclude
Chỉ tìm trong TypeScript:
rg "createClient" -g '*.ts' -g '*.tsx'
Bỏ qua test:
rg "localStorage" -g '!*.test.ts' -g '!*.spec.ts'
Bỏ qua thư mục:
rg "apiKey" -g '!dist/**' -g '!coverage/**'
Tìm trong cả file bị ignore:
rg --hidden --glob '!.git/**' "MY_ENV_VAR"
--hidden sẽ đọc dotfile như .env.example, .github/workflows, .npmrc. Luôn exclude .git/** nếu bạn không muốn search vào object database của Git.
rg --files: liệt kê file theo ignore rules
Đôi khi bạn không cần tìm nội dung, chỉ cần danh sách file:
rg --files
rg --files | rg 'package.json|tsconfig.json|vite.config'
rg --files src/content/posts | rg 'bash-|docker-'
Đếm số MDX posts:
rg --files src/content/posts | rg '\\.mdx$' | wc -l
Đây là combo rất nhanh: rg --files tạo danh sách file, pipe sang rg thứ hai để lọc tên.
find: tìm file theo thuộc tính
find có sẵn gần như mọi nơi.
find . -name '*.log'
find src -type f -name '*.ts'
find . -type d -name node_modules
Tìm file mới sửa trong 24 giờ:
find . -type f -mtime -1
Tìm file lớn hơn 5MB:
find . -type f -size +5M -print
Tìm và xóa file tạm, nhưng hãy dry-run trước:
find . -name '*.tmp' -print
find . -name '*.tmp' -delete
-delete là thao tác thật. Luôn chạy bản -print trước.
fd: find thân thiện hơn
Nếu có thể cài thêm, fd là phiên bản dễ dùng hơn của find.
fd package.json
fd -e mdx
fd bash src/content/posts
fd -H '^\\.env'
| Nhu cầu | find | fd |
|---|---|---|
| Có sẵn mặc định | Rất cao | Thường cần cài |
| Cú pháp | Dài | Ngắn |
Tôn trọng .gitignore | Không mặc định | Có |
| Search hidden | Cần điều kiện riêng | -H |
Nếu repo/team chưa dùng fd, cứ dùng find. Nếu máy cá nhân của bạn có fd, nó làm việc hàng ngày rất sướng.
Null separator: xử lý tên file có space
Tên file có space làm vỡ pipeline kiểu cũ:
find . -name '*.mdx' | xargs wc -l
An toàn hơn:
find . -name '*.mdx' -print0 | xargs -0 wc -l
Với rg:
rg -l --null "TODO" | xargs -0 sed -n '1,20p'
Quy tắc: khi output là danh sách file đưa sang lệnh khác, ưu tiên -print0 và xargs -0.
Recipe developer hay dùng
Tìm mọi nơi dùng một env var:
rg --hidden --glob '!.git/**' "OPENAI_API_KEY|DATABASE_URL"
Tìm route hoặc page:
rg --files src/pages | sort
Tìm import từ package cụ thể:
rg "from ['\\\"]@tanstack/react-query['\\\"]" src
Tìm TODO/FIXME có context:
rg -n -C 2 "TODO|FIXME|HACK" src
Tìm file config ở root và cấp 2:
find . -maxdepth 2 -type f \\( -name '*config*' -o -name '.*rc' -o -name '*.json' \\) -print
Bài tập
- Dùng
rgtìm mọi bài trong repo có tagbash. - Dùng
rg --filesliệt kê tất cả file.astro. - Dùng
findtìm file lớn hơn 1MB. - Dùng
rg -C 2tìm nơi dùngseriesOrder.
Lời giải tham khảo
rg "tags: .*bash" src/content/posts
rg --files | rg '\\.astro$'
find . -type f -size +1M -print
rg -C 2 "seriesOrder"Điều cốt lõi
Dùng rg để tìm nội dung, rg --files hoặc find/fd để tìm file, và dùng glob/exclude để giữ kết quả nhỏ. Search tốt là kỹ năng đọc codebase nhanh, không chỉ là tiện ích terminal.