Jak użyć polecenia find, aby znaleźć wszystkie pliki z rozszerzeniami z listy?

179

Muszę znaleźć wszystkie pliki obrazów z katalogu (gif, png, jpg, jpeg).

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

Jak zmodyfikować ten ciąg, aby znaleźć nie tylko pliki .jpg?

Kirzilla
źródło

Odpowiedzi:

190
find /path/to -regex ".*\.\(jpg\|gif\|png\|jpeg\)" > log
Wstrzymano do odwołania.
źródło
6
Nie działa dla mnie na Macu, ale działa z opcją -E (rozszerzona) (może potok jest rozszerzoną funkcją?): Znajdź -E / path / to -iregex ". * \. (Jpg | gif | png | jpeg) "> log
ling
138
find /path/to/  \( -iname '*.gif' -o -iname '*.jpg' \) -print0

będzie działać. Może być bardziej elegancki sposób.

JoseK
źródło
16
-iname nie rozróżnia wielkich i małych liter
Chris Koston
1
@ Gerald: Prawdopodobnie musisz pogrupować wyrażenie OR w nawiasach, które find /path/to/ \( -iname '*.gif' -o -iname '*.jpg' \) -exec ls -l {} \;nie mają znaczenia : w przeciwnym razie exec ma zastosowanie tylko do ostatniej części ( -iname '*.jpg' w tym przypadku).
Wstrzymano do odwołania.
To ważna uwaga. find /path/to/ -iname '*.gif' -o -iname '*.jpg' -print0wydrukuje tylko pliki jpg! Potrzebujesz nawiasów tutaj:find /path/to/ \( -iname '*.gif' -o -iname '*.jpg' \) -print0
Anne van Rossum
28

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

-EPozwala uniknąć konieczności ucieczki parens i rur w Twojej regex.

tboyce12
źródło
2
moje znalezisko nie ma tego -E
wieczorek1990
1
Hmmm -Eopcja mówi findo użyciu „rozszerzonych wyrażeń regularnych”. Kilka innych narzędzi ma podobną opcję, ale nie jestem pewien, czy ta opcja jest dostępna we wszystkich dystrybucjach UNIX.
tboyce12
8
Działa również w systemie Mac OS.
c.gutierrez
2
@ tboyce12 robocza na ubuntu, mogę określić -regextype uproszczenia regex wyrażenie: find . -regextype posix-extended -regex ".*\.(jpg|gif|png|jpeg)".
doub1ejack
1
@cjm Może find -E /path/to -iregex ".*\.(jpg|gif|png|jpeg)" > log. Użycie -iregexflagi informuje, findże wielkość liter nie ma znaczenia.
tboyce12
11
find /path/to/ -type f -print0 | xargs -0 file | grep -i image

Używa tego filepolecenia, aby spróbować rozpoznać typ pliku, niezależnie od nazwy pliku (lub rozszerzenia).

Jeśli /path/tolub nazwa pliku zawiera ciąg image, powyższe może zwrócić fałszywe trafienia. W takim razie sugerowałbym

cd /path/to
find . -type f -print0 | xargs -0 file --mime-type | grep -i image/
unutbu
źródło
Przepraszam, miałem tam błędne kliknięcie i najwyraźniej nie mogę cofnąć głosowania ... :(
Mark Simpson
6
find /path -type f \( -iname "*.jpg" -o -name "*.jpeg" -o -iname "*gif" \)
ghostdog74
źródło
2
Czy możesz wyjaśnić, dlaczego dodałeś (ucieczkowe) nawiasy wokół parametrów nazwa / nazwa?
Bart Kleijngeld,
Czy jest jakiś powód niespójności? -iname *.jpg, -o -name *.jpeg, -o -iname *gifMają nieco inny format.
Opuszczony
jeśli potrafisz przynajmniej wyjaśnić różnice innymi odpowiedziami.
el-teedee
6

Oprócz powyższej odpowiedzi @Dennis Williamson, jeśli chcesz, aby ten sam wyrażenie regularne nie rozróżniało wielkości liter w rozszerzeniach plików, użyj opcji -iregex:

find /path/to -iregex ".*\.\(jpg\|gif\|png\|jpeg\)" > log
TCW
źródło
5

W systemie Mac OS

find -E packages  -regex ".*\.(jpg|gif|png|jpeg)"
7ynk3r
źródło
3
find -regex ".*\.\(jpg\|gif\|png\|jpeg\)"
shrikant
źródło
-1

w przypadku, gdy pliki nie mają rozszerzenia, możemy poszukać typu MIME pliku

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

gdzie (audio | wideo | matroska | mpeg) są wyrażeniami regularnymi typu MIME

a jeśli chcesz je usunąć:

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

lub usuń wszystko inne oprócz tych rozszerzeń:

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

zwróć uwagę na! ~ zamiast ~

k. Łania
źródło