Lệnh find trong Linux: tìm file theo tên, kích thước và ngày sửa — ví dụ
Lệnh find duyệt cây thư mục và chọn file theo điều kiện: find /path -name '*.log' tìm theo tên, -type f chỉ lấy file, -size +100M lớn hơn 100 MB, -mtime -7 được sửa trong vòng một tuần. Các điều kiện có thể kết hợp, và trên kết quả tìm được có thể chạy hành động qua -exec, -delete hoặc chuyển danh sách cho xargs.
Lệnh find duyệt cây thư mục và tìm file theo các điều kiện: tên, loại, kích thước, thời gian sửa đổi, chủ sở hữu và quyền. Cấu trúc chung là find [nơi tìm] [điều kiện] [hành động]. Dưới đây là các ví dụ find linux cho những việc thường gặp: tìm file cấu hình, dọn log cũ, xác định thứ đang chiếm chỗ trên đĩa.
Cú pháp lệnh find
find /var/log -type f -name '*.log' -mtime +30 -print
Phân tích từng phần:
/var/log— điểm bắt đầu. Có thể liệt kê nhiều thư mục liên tiếp hoặc dùng.(thư mục hiện tại). Nếu không có đường dẫn, GNU find tìm trong thư mục hiện tại.-type f -name '*.log' -mtime +30— các điều kiện (trong tài liệu gọi là test). Giữa chúng mặc định là phép «VÀ» (AND).-print— hành động: in đường dẫn. Nó được áp dụng tự động nếu không có hành động nào khác.
find đi đệ quy vào mọi thư mục con. Nếu chạy bằng người dùng thường trên các đường dẫn hệ thống, đầu ra sẽ bị lấp đầy bởi dòng Permission denied. Hãy bỏ chúng bằng cách chuyển luồng lỗi đi:
find / -name 'nginx.conf' 2>/dev/null
Tìm theo tên: -name và -iname
Điều kiện -name chỉ so sánh tên file (không kèm đường dẫn) với mẫu. Mẫu hỗ trợ * (mọi ký tự), ? (một ký tự) và [abc] (một trong các ký tự được liệt kê).
# tên chính xác
find /etc -name 'hosts'
# tất cả file .conf
find /etc -name '*.conf'
# không phân biệt hoa thường: README.md, readme.MD, Readme.md
find ~/projects -iname 'readme.md'
# report_1.csv ... report_9.csv
find . -name 'report_?.csv'
Luôn đặt mẫu trong dấu nháy. Nếu không, shell sẽ tự mở rộng *.conf theo các file trong thư mục hiện tại, và find nhận được danh sách tên thay vì mẫu, kết quả sẽ khó đoán hoặc lệnh báo lỗi paths must precede expression.
Tìm theo đường dẫn: -path và -regex
Nếu quan trọng là thư mục chứ không chỉ tên, hãy dùng -path. Nó so khớp mẫu với toàn bộ đường dẫn:
# file .js chỉ nằm trong các thư mục src
find . -path '*/src/*' -name '*.js'
Với mẫu phức tạp có -regex (biểu thức chính quy cũng áp dụng trên toàn bộ đường dẫn) và -iregex không phân biệt hoa thường:
find . -regextype posix-extended -regex '.*\.(jpg|jpeg|png)$'
Cách loại trừ một thư mục
Để find không đi vào, chẳng hạn, node_modules hay .git, dùng -prune:
find . -path ./node_modules -prune -o -name '*.js' -print
Đọc như sau: «nếu đường dẫn là ./node_modules thì không đi xuống trong đó, còn không thì (-o) in các file *.js». Phải có -print ở cuối, nếu không thư mục bị loại trừ cũng sẽ xuất hiện trong kết quả. Cách đơn giản hơn nhưng chậm hơn là -not -path '*/node_modules/*': find vẫn duyệt thư mục đó, chỉ lọc kết quả.
Tìm theo loại: -type
| Giá trị | Tìm gì |
|---|---|
-type f | file thông thường |
-type d | thư mục |
-type l | liên kết tượng trưng (symlink) |
-type s | socket |
-type p | pipe có tên (FIFO) |
# chỉ thư mục có tên logs
find / -type d -name 'logs' 2>/dev/null
# file rỗng và thư mục rỗng
find . -type f -empty
find . -type d -empty
# liên kết tượng trưng bị hỏng
find . -xtype l
Tìm theo kích thước: -size
Điều kiện -size nhận một số kèm hậu tố: c — byte, k — kilobyte, M — megabyte, G — gigabyte. Dấu + nghĩa là «lớn hơn», - là «nhỏ hơn», không có dấu là «đúng bằng».
# file lớn hơn 100 MB trong toàn hệ thống
find / -type f -size +100M 2>/dev/null
# từ 10 đến 50 MB
find . -type f -size +10M -size -50M
# nhỏ hơn 1 KB
find . -type f -size -1k
Có một lưu ý: kích thước được làm tròn lên theo đơn vị. Vì vậy -size -1M chỉ tìm được file rỗng, vì mọi file không rỗng sau khi làm tròn đều «ít nhất 1 megabyte». Để có ngưỡng chính xác, hãy dùng đơn vị nhỏ hơn: -size -1024k.
Thứ gì đang chiếm dung lượng đĩa
Kết hợp find với ls và sort sẽ cho thấy các file lớn nhất:
find /var -type f -size +50M -exec ls -lh {} + 2>/dev/null | sort -k5 -rh | head
-rw-r----- 1 syslog adm 1.2G Oct 14 09:12 /var/log/syslog.1
-rw-r--r-- 1 root root 412M Oct 10 03:00 /var/backups/db.sql.gz
-rw-r----- 1 root adm 96M Oct 14 09:15 /var/log/nginx/access.log
Để ước lượng cả thư mục, du -sh tiện hơn; còn find hữu ích khi dung lượng bị chiếm bởi một file khổng lồ nằm sâu bên trong.
Tìm theo ngày: -mtime, -mmin, -newer
Mỗi file có ba mốc thời gian, và find có thể lọc theo từng mốc:
| Điều kiện | Mốc thời gian | Đơn vị |
|---|---|---|
-mtime / -mmin | thay đổi nội dung | ngày / phút |
-atime / -amin | lần đọc gần nhất | ngày / phút |
-ctime / -cmin | thay đổi metadata (quyền, chủ sở hữu, tên) | ngày / phút |
Dấu hoạt động giống như với kích thước: -mtime -7 là file được sửa cách đây chưa tới 7 ngày, -mtime +30 là cách đây hơn 30 ngày.
# được sửa trong tuần qua
find ~/projects -type f -mtime -7
# log cũ hơn 30 ngày
find /var/log -type f -name '*.log' -mtime +30
# được sửa trong 15 phút gần đây
find /etc -type f -mmin -15
Ngày được tính theo chu kỳ nguyên 24 giờ, phần lẻ bị bỏ qua. Vì thế -mtime +1 tìm các file cũ hơn 48 giờ, chứ không phải 24 giờ, và đây là bẫy hay gặp. Nếu cần độ chính xác, hãy chuyển sang phút: -mmin +1440.
File mới hơn một file khác hoặc một mốc ngày
# được sửa sau khi deploy.lock được thay đổi
find . -type f -newer deploy.lock
# được sửa sau một ngày cụ thể (GNU find)
find . -type f -newermt '2026-10-01'
# trong khoảng ngày
find . -type f -newermt '2026-10-01' ! -newermt '2026-10-08'
Tìm theo chủ sở hữu và quyền
# file của người dùng alice
find /home -user alice
# file không có chủ sở hữu hợp lệ (sau khi xóa người dùng)
find / -nouser 2>/dev/null
# file có quyền đúng 777
find /var/www -type f -perm 777
# file mà mọi người đều có quyền ghi
find /var/www -perm -o=w
# file có bit SUID — hữu ích khi kiểm tra bảo mật
find / -perm -4000 -type f 2>/dev/null
Tham số -perm có ba dạng: không dấu — quyền khớp chính xác; dấu - — ít nhất tất cả các bit được chỉ định đều được bật; dấu / — ít nhất một trong các bit được chỉ định được bật.
Logic điều kiện: VÀ, HOẶC, KHÔNG
Các điều kiện mặc định nối với nhau bằng «VÀ». Để dùng «HOẶC» có -o, để phủ định có ! hoặc -not. Nhóm điều kiện bằng dấu ngoặc, và các dấu ngoặc này cần được escape để shell không xử lý:
# ảnh jpg hoặc png
find . -type f \( -name '*.jpg' -o -name '*.png' \)
# mọi thứ trừ file .tmp
find . -type f ! -name '*.tmp'
Không có ngoặc thì -type f chỉ áp dụng cho điều kiện đầu tiên của cặp «HOẶC», và kết quả sẽ chứa cả các thư mục có tên *.png. Phải có khoảng trắng quanh \( và \).
Độ sâu tìm kiếm: -maxdepth và -mindepth
# chỉ trong thư mục hiện tại, không đi vào thư mục con
find . -maxdepth 1 -type f -name '*.sh'
# bắt đầu từ cấp lồng thứ hai
find . -mindepth 2 -name '*.md'
# không chuyển sang hệ thống file khác
find / -xdev -type f -size +1G
Đặt -maxdepth ngay sau đường dẫn, trước các điều kiện khác, nếu không GNU find sẽ đưa ra cảnh báo. Tùy chọn -xdev hữu ích khi tìm từ /: find sẽ không đi vào /proc, các ổ đĩa mạng và ổ đĩa được gắn kết.
Hành động trên kết quả: -exec, -delete, xargs
-exec: chạy lệnh cho từng file
Thay vì {}, find sẽ thế đường dẫn file vào. Lệnh kết thúc bằng \; hoặc +:
# mỗi file chạy một lần
find . -name '*.sh' -exec chmod +x {} \;
# gom tất cả file thành một danh sách — nhanh hơn
find . -name '*.log' -exec gzip {} +
# hỏi xác nhận cho từng file
find . -name '*.bak' -ok rm {} \;
Dạng với + gom đường dẫn thành từng nhóm và chạy lệnh ít lần hơn, nên với hàng nghìn file nó nhanh hơn gấp nhiều lần. Dạng với \; cần khi lệnh chỉ nhận một file hoặc {} không nằm ở cuối.
-delete: xóa những gì tìm được
# xem trước những gì sẽ bị xóa
find /tmp/build -type f -name '*.o' -mtime +7
# sau đó mới xóa
find /tmp/build -type f -name '*.o' -mtime +7 -delete
Luôn chạy lệnh không có -delete và kiểm tra danh sách trước. Đặt -delete ở cuối: find đánh giá biểu thức từ trái sang phải, nên find . -delete -name '*.o' sẽ xóa toàn bộ nội dung thư mục rồi mới kiểm tra tên.
find và xargs
Cách kết hợp kinh điển là chuyển danh sách file cho chương trình khác qua xargs. Để không bị lỗi với tên có khoảng trắng, hãy dùng ký tự phân tách là byte rỗng:
find . -type f -name '*.txt' -print0 | xargs -0 wc -l
Tùy chọn -P của xargs cho phép xử lý song song:
find ./images -name '*.png' -print0 | xargs -0 -P 4 -n 10 optipng
find và grep: tìm văn bản bên trong file
find tìm file chứ không đọc nội dung. Để tìm một chuỗi bên trong các file đã chọn, hãy chuyển chúng cho grep:
# tìm nơi trong các file cấu hình có dòng listen 8080
find /etc/nginx -type f -name '*.conf' -exec grep -Hn 'listen 8080' {} +
/etc/nginx/sites-enabled/app.conf:4: listen 8080;
Cờ -H in tên file, -n in số dòng, còn grep -l chỉ in tên các file có khớp. Nếu chỉ cần lọc theo phần mở rộng, chỉ cần grep: grep -rn --include='*.conf' 'listen 8080' /etc/nginx.
Định dạng đầu ra tùy chỉnh: -printf
GNU find có thể in không chỉ đường dẫn. Ví dụ, in kích thước, ngày và tên:
find . -maxdepth 1 -type f -printf '%s\t%TY-%Tm-%Td\t%p\n' | sort -n
Ở đây %s là kích thước tính bằng byte, %T... là ngày sửa đổi theo từng phần, %p là đường dẫn. Điều này tiện cho script: không phải phân tích đầu ra của ls.
Bảng tra cứu nhanh: ví dụ find linux hằng ngày
| Việc cần làm | Lệnh |
|---|---|
| Tìm file theo tên | find / -name 'file.txt' 2>/dev/null |
| Không phân biệt hoa thường | find . -iname '*.jpg' |
| Chỉ thư mục | find . -type d -name 'cache' |
| File lớn hơn 1 GB | find / -xdev -type f -size +1G |
| Được sửa trong một ngày | find . -type f -mtime -1 |
| Được sửa trong một giờ | find . -type f -mmin -60 |
| Xóa log cũ hơn 30 ngày | find /var/log/app -name '*.log' -mtime +30 -delete |
| Thư mục rỗng | find . -type d -empty |
| Đổi quyền cho mọi thư mục | find . -type d -exec chmod 755 {} + |
| Chuỗi bên trong file | find . -name '*.py' -exec grep -l 'TODO' {} + |
| Đếm file | find . -type f | wc -l |
Lỗi thường gặp
- Mẫu không có dấu nháy.
find . -name *.logsẽ hỏng nếu thư mục hiện tại có ít nhất một file.log. Hãy viết'*.log'. - Hàng loạt Permission denied. Thêm
2>/dev/null, hoặc chạy bằngsudonếu thực sự cần quét toàn bộ đĩa. -deleteđặt sai chỗ. Nó luôn ở cuối, và trước nó nên có một lần chạy thử không xóa.- Tên có khoảng trắng trong pipeline.
find ... | xargs rmsẽ tách «My File.txt» thành hai đối số. Hãy dùng-print0vớixargs -0, hoặc-exec. - Kỳ vọng
-mtimecho số ngày chính xác. Với khoảng thời gian chính xác, hãy dùng-mminhoặc-newermt.
Tổng kết
find là công cụ đa năng để tìm trong hệ thống file: đường dẫn, các điều kiện theo tên, loại, kích thước, ngày và quyền, rồi đến hành động. Nắm vững năm trụ cột — -name, -type, -size, -mtime và -exec ... + — là đủ giải quyết hầu hết việc bằng một dòng lệnh. Hãy thử lại các ví dụ find linux này trên terminal của bạn, còn việc kết hợp find với grep, sed và awk được thực hành trong bài giảng về xử lý văn bản trong terminal của khóa học Linux.
Câu hỏi thường gặp
find khác locate ở điểm nào?
locate tìm trong một cơ sở dữ liệu tên được xây dựng sẵn, nên chạy tức thì nhưng không thấy các file tạo sau lần cập nhật cơ sở dữ liệu gần nhất bằng lệnh updatedb. find duyệt đĩa theo thời gian thực và có thể lọc theo kích thước, ngày và quyền.
Làm sao tìm file theo nội dung thay vì theo tên?
Bản thân find không đọc nội dung. Hãy dùng grep -rn 'văn-bản' /đường/dẫn, hoặc kết hợp find . -name '*.conf' -exec grep -l 'văn-bản' {} +.
Vì sao find chạy chậm khi tìm từ thư mục gốc?
Nó duyệt mọi thư mục, kể cả /proc, /sys và các ổ đĩa được gắn kết. Hãy giới hạn tìm kiếm trong một thư mục cụ thể, thêm -xdev và -maxdepth, hoặc loại trừ phần thừa bằng -prune.
Có thể sắp xếp kết quả find theo ngày không?
Có: find . -type f -printf '%T@ %p\n' | sort -n liệt kê file từ cũ đến mới, trong đó %T@ là thời gian sửa đổi tính bằng giây kể từ mốc epoch.
Làm sao tìm và xóa các thư mục rỗng?
Lệnh find . -type d -empty -delete xóa mọi thư mục rỗng, kể cả những thư mục vừa trở nên rỗng sau khi xóa thư mục con. Hãy chạy thử không có -delete và kiểm tra danh sách trước.
Chủ đề này được giảng chi tiết kèm thực hành trong khóa học “Linux: с нуля до уверенного администрирования”.
Đến khóa học