Bagaimana cara menggunakan perintah find untuk menemukan semua file dengan ekstensi dari daftar?

179

Saya perlu menemukan semua file gambar dari direktori (gif, png, jpg, jpeg).

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

Bagaimana cara memodifikasi string ini untuk menemukan tidak hanya file .jpg?

Kirzilla
sumber

Jawaban:

191
find /path/to -regex ".*\.\(jpg\|gif\|png\|jpeg\)" > log
Dijeda sampai pemberitahuan lebih lanjut.
sumber
6
Tidak berfungsi untuk saya di mac, tetapi bekerja dengan opsi -E (extended) (mungkin pipa adalah fitur tambahan?): Find -E / path / to -iregex ". * \. (Jpg | gif | png | jpeg) "> log
ling
138
find /path/to/  \( -iname '*.gif' -o -iname '*.jpg' \) -print0

akan bekerja. Mungkin ada cara yang lebih elegan.

JoseK
sumber
16
-iname tidak peka huruf besar-kecil
Chris Koston
1
@ Emerald: Kemungkinan Anda perlu mengelompokkan ekspresi ATAU Anda dalam tanda kurung lolos: find /path/to/ \( -iname '*.gif' -o -iname '*.jpg' \) -exec ls -l {} \;jika eksekutif hanya berlaku untuk bagian terakhir ( -iname '*.jpg' dalam hal ini).
Dijeda sampai pemberitahuan lebih lanjut.
Itu komentar yang penting. find /path/to/ -iname '*.gif' -o -iname '*.jpg' -print0hanya akan mencetak file jpg! Anda membutuhkan tanda kurung di sini:find /path/to/ \( -iname '*.gif' -o -iname '*.jpg' \) -print0
Anne van Rossum
28

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

The -Emenyelamatkan Anda dari keharusan untuk melarikan diri parens dan pipa di regex Anda.

tboyce12
sumber
2
Temuan
1
Hmmm -Eopsi memberitahu finduntuk menggunakan "ekspresi reguler yang diperluas". Beberapa alat lain memiliki opsi serupa, tetapi saya tidak yakin opsi ini tersedia di semua distribusi UNIX.
tboyce12
8
Bekerja di Mac OS juga.
c.gutierrez
2
@ tboyce12 Kerja ubuntu, saya bisa menentukan -regextype untuk menyederhanakan ekspresi regex: find . -regextype posix-extended -regex ".*\.(jpg|gif|png|jpeg)".
doub1ejack
1
@ cjm Mungkin find -E /path/to -iregex ".*\.(jpg|gif|png|jpeg)" > log. Menggunakan -iregexflag memberitahu finduntuk mencocokkan case dengan tidak sensitif.
tboyce12
11
find /path/to/ -type f -print0 | xargs -0 file | grep -i image

Ini menggunakan fileperintah untuk mencoba mengenali jenis file, terlepas dari nama file (atau ekstensi).

Jika /path/toatau nama file berisi string image, maka di atas dapat mengembalikan hit palsu. Dalam hal ini, saya sarankan

cd /path/to
find . -type f -print0 | xargs -0 file --mime-type | grep -i image/
unutbu
sumber
Maaf, ada klik yang salah di sana dan saya tampaknya tidak dapat membatalkan downvote ... :(
Mark Simpson
6
find /path -type f \( -iname "*.jpg" -o -name "*.jpeg" -o -iname "*gif" \)
ghostdog74
sumber
2
Bisakah Anda menjelaskan mengapa Anda menambahkan tanda kurung (lolos) di sekitar parameter nama / iname?
Bart Kleijngeld
Ada alasan untuk ketidakkonsistenan? -iname *.jpg, -o -name *.jpeg, -o -iname *gifSemua memiliki format yang sedikit berbeda.
Keranjang Terbengkalai
jika Anda setidaknya bisa menjelaskan perbedaan dengan jawaban lain.
el-teedee
6

Sebagai tambahan terhadap respons @Dennis Williamson di atas, jika Anda ingin regex yang sama tidak peka terhadap ekstensi file, gunakan -iregex:

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

Pada penggunaan Mac OS

find -E packages  -regex ".*\.(jpg|gif|png|jpeg)"
7ynk3r
sumber
3
find -regex ".*\.\(jpg\|gif\|png\|jpeg\)"
nyentrik
sumber
-1

jika file tidak memiliki ekstensi, kita dapat mencari jenis file mime

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

di mana (audio | video | matroska | mpeg) adalah jenis mime regex

& jika Anda ingin menghapusnya:

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

atau hapus semua yang lain kecuali ekstensi itu:

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

perhatikan! ~ bukannya ~

k. Kelinci betina
sumber