Hướng dẫn

Lệnh find trong Linux: tìm file theo tên, kích thước và ngày sửa — ví dụ

Cập nhật: · Skillaria.Top

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 ffile thông thường
-type dthư mục
-type lliên kết tượng trưng (symlink)
-type ssocket
-type ppipe 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ệnMốc thời gianĐơn vị
-mtime / -mminthay đổi nội dungngày / phút
-atime / -aminlần đọc gần nhấtngày / phút
-ctime / -cminthay đổ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àmLệnh
Tìm file theo tênfind / -name 'file.txt' 2>/dev/null
Không phân biệt hoa thườngfind . -iname '*.jpg'
Chỉ thư mụcfind . -type d -name 'cache'
File lớn hơn 1 GBfind / -xdev -type f -size +1G
Được sửa trong một ngàyfind . -type f -mtime -1
Được sửa trong một giờfind . -type f -mmin -60
Xóa log cũ hơn 30 ngàyfind /var/log/app -name '*.log' -mtime +30 -delete
Thư mục rỗngfind . -type d -empty
Đổi quyền cho mọi thư mụcfind . -type d -exec chmod 755 {} +
Chuỗi bên trong filefind . -name '*.py' -exec grep -l 'TODO' {} +
Đếm filefind . -type f | wc -l

Lỗi thường gặp

  • Mẫu không có dấu nháy. find . -name *.log sẽ 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ằng sudo nế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 rm sẽ tách «My File.txt» thành hai đối số. Hãy dùng -print0 với xargs -0, hoặc -exec.
  • Kỳ vọng -mtime cho số ngày chính xác. Với khoảng thời gian chính xác, hãy dùng -mmin hoặ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.

Học chủ đề này qua video

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