Jak połączyć warunki 2-name w find?

94

Chciałbym wyszukać pliki, które nie pasują do 2 -namewarunków. Mogę to zrobić tak:

find /media/d/ -type f -size +50M ! -name "*deb" ! -name "*vmdk"

i to da właściwy wynik, ale czy mogę jakoś połączyć te 2 warunki z LUB?

Patryk
źródło

Odpowiedzi:

46

Możesz to zrobić również przy użyciu negacji -regex: -

 find ./ ! -regex  '.*\(deb\|vmdk\)$'
Alex Leach
źródło
6
Pamiętaj, że -regexjest mniej przenośny niż -name.
jw013,
145

tak, możesz:

find /media/d/ -type f -size +50M ! \( -name "*deb" -o -name "*vmdk" \)

Objaśnienie ze specyfikacji POSIX :

! wyrażenie : Negacja pierwszorzędnej; jednoargumentowy operator NOT.

( wyrażenie ): Prawda, jeśli wyrażenie jest prawdziwe.

wyrażenie -o wyrażenie : Alternacja pierwotnych; operator OR. Drugie wyrażenie nie będzie oceniane, jeśli pierwsze wyrażenie jest prawdziwe.

Zauważ, że nawiasy otwierające i zamykające są poprzedzone odwrotnym ukośnikiem ( \), aby zapobiec ocenie przez powłokę.

Serge
źródło
2
Jeśli wykonujesz -execinne czynności na findwynikach, pamiętaj o nawiasowaniu \( \)całych kryteriów, w przeciwnym razie -execbędzie miało zastosowanie tylko do ostatniego -orkryterium. Aby pracować nad wszystkimi, nawiasuj je:find \( <criterion> -o <criterion> \) -exec <command>
Victor Sergienko
25

Jesteś blisko rozwiązania:

find /media/d/ -type f -size +50M -and ! -name "*deb" -and ! -name "*vmdk"

Możesz łączyć następujące operatory logiczne w dowolnej kolejności:

-a   -and      - operator AND
-o   -or       - operator OR
!              - operator NOT
DenisKolodin
źródło
6

Możesz używać wyrażeń regularnych jak w:

find /media/d -type f -size +50M ! -regex '\(.*deb\|.*vmdk\)'

Odwrotny ukośnik jest znakiem ucieczki; .dopasowuje pojedynczy znak i *służy do dopasowania poprzedniego znaku zero lub więcej razy, więc .*oznacza dopasowanie zero lub więcej znaków.

Francesco Turco
źródło
1
Dodanie wyjaśnienia poprawiłoby twoją odpowiedź.
NN
Masz rację. Dodano kilka wyjaśnień.
Francesco Turco