Làm cách nào để sử dụng lệnh find để tìm tất cả các tệp có phần mở rộng từ danh sách?


179

Tôi cần tìm tất cả các tập tin hình ảnh từ thư mục (gif, png, jpg, jpeg).

find /path/to/ -name "*.jpg" > log

Làm cách nào để sửa đổi chuỗi này để tìm không chỉ các tệp .jpg?

Câu trả lời:


191
find /path/to -regex ".*\.\(jpg\|gif\|png\|jpeg\)" > log

6
Không hoạt động với tôi trên mac, nhưng hoạt động với tùy chọn -E (mở rộng) (có thể đường ống là một tính năng mở rộng?): Find -E / path / to -iregex ". * \. (Jpg | gif | png | jpeg)"> đăng nhập
ling

138
find /path/to/  \( -iname '*.gif' -o -iname '*.jpg' \) -print0

sẽ làm việc. Có thể có một cách thanh lịch hơn.


16
-iname sẽ không nhạy cảm
Chris Koston

1
@Gerald: Có thể bạn cần nhóm biểu thức OR của mình trong dấu ngoặc đơn đã thoát: find /path/to/ \( -iname '*.gif' -o -iname '*.jpg' \) -exec ls -l {} \;nếu không thì hàm thực thi chỉ áp dụng cho phần cuối cùng ( -iname '*.jpg' trong trường hợp này).
Tạm dừng cho đến khi có thông báo mới.

Đó là một nhận xét quan trọng. find /path/to/ -iname '*.gif' -o -iname '*.jpg' -print0sẽ chỉ in các tập tin jpg! Bạn cần ngoặc ở đây:find /path/to/ \( -iname '*.gif' -o -iname '*.jpg' \) -print0
Anne van Rossum

28

find -E /path/to -regex ".*\.(jpg|gif|png|jpeg)" > log

Việc -Etiết kiệm cho bạn khỏi phải thoát khỏi parens và ống dẫn trong regex của bạn.


2
phát hiện của tôi không có cái này -E
wieczorek1990

1
Hmmm -Etùy chọn yêu findcầu sử dụng "biểu thức chính quy mở rộng". Một số công cụ khác có tùy chọn tương tự, nhưng tôi không chắc tùy chọn này có sẵn trên tất cả các bản phân phối UNIX.
tboyce12

8
Hoạt động trên Mac OS cũng vậy.
c.gutierrez

2
@ tboyce12 Hoạt động trên Ubuntu, tôi có thể chỉ định -regextype để đơn giản hóa biểu thức regex : find . -regextype posix-extended -regex ".*\.(jpg|gif|png|jpeg)".
ngờ1ejack

1
@cjm Có lẽ find -E /path/to -iregex ".*\.(jpg|gif|png|jpeg)" > log. Sử dụng -iregexcờ cho findphù hợp với trường hợp không nhạy cảm.
tboyce12

11
find /path/to/ -type f -print0 | xargs -0 file | grep -i image

Điều này sử dụng filelệnh để cố gắng nhận ra loại tệp, bất kể tên tệp (hoặc phần mở rộng).

Nếu /path/tohoặc một tên tệp chứa chuỗi image, thì ở trên có thể trả về các lần truy cập không có thật. Trong trường hợp đó, tôi đề nghị

cd /path/to
find . -type f -print0 | xargs -0 file --mime-type | grep -i image/

Xin lỗi, đã có một cú nhấp chuột sai lầm ở đó và tôi dường như không thể hoàn tác downvote ... :(
Mark Simpson

6
find /path -type f \( -iname "*.jpg" -o -name "*.jpeg" -o -iname "*gif" \)

2
Bạn có thể giải thích lý do tại sao bạn thêm dấu ngoặc đơn (thoát) xung quanh các tham số tên / iname không?
Bart Kleijngeld

Bất kỳ lý do cho sự không nhất quán? -iname *.jpg, -o -name *.jpeg, -o -iname *gifTất cả đều có một định dạng hơi khác nhau.
Giỏ hàng bị bỏ rơi

nếu bạn ít nhất có thể giải thích sự khác biệt với các câu trả lời khác.
el-teedee

6

Để bổ sung cho phản hồi của @Dennis Williamson ở trên, nếu bạn muốn regex tương tự không phân biệt chữ hoa chữ thường đối với phần mở rộng tệp, hãy sử dụng -iregex:

find /path/to -iregex ".*\.\(jpg\|gif\|png\|jpeg\)" > log

5

Trên Mac OS sử dụng

find -E packages  -regex ".*\.(jpg|gif|png|jpeg)"


-1

trong trường hợp tập tin không có phần mở rộng, chúng tôi có thể tìm loại tập tin mime

find . -type f -exec file -i {} + | awk -F': +' '{ if ($2 ~ /audio|video|matroska|mpeg/) print $1 }'

trong đó (audio | video | matroska | mpeg) là loại mime regex

& nếu bạn muốn xóa chúng:

find . -type f -exec file -i {} + | awk -F': +' '{ if ($2 ~ /audio|video|matroska|mpeg/) print $1 }' | while read f ; do
  rm "$f"
done

hoặc xóa mọi thứ khác trừ những phần mở rộng đó:

find . -type f -exec file -i {} + | awk -F': +' '{ if ($2 !~ /audio|video|matroska|mpeg/) print $1 }' | while read f ; do
  rm "$f"
done

chú ý! ~ thay vì ~

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.