Jak mogę wykluczyć katalog podczas korzystania z funkcji Znajdź

6

Próbuję użyć polecenia find w systemie Unix i wiem, jak korzystać z jego podstaw. Na przykład mam cztery foldery, A, B, C i D. W każdym folderze mam plik o nazwie hi.dat. Aby zajrzeć do wszystkich folderów, zrobiłbym:

find * -name hi.dat.

Świetny! Ale co teraz, jeśli nie chcę patrzeć na folder D? Czy mogę spróbować czegoś takiego:

find * not D/* -name hi.dat?

Nie chcę pisać:

find A/* B/* C/* -name ... ponieważ oczywiście mam więcej niż trzy foldery, które zostały użyte jako przykład.

Dzięki! Amit

Amit
źródło

Odpowiedzi:

11

W Bash:

shopt -s extglob
find !(D) -name hi.dat

Ksh i zsh działają podobnie.

Dennis Williamson
źródło
o stary. więc czy wpisuję to w wierszu poleceń?
Amit
3
@Amit: Tak, gdzie jeszcze? Ta extglobopcja może być już ustawiona. Możesz to sprawdzić, wykonując czynność shopt extglob, jeśli jest napisane „wł.”, Masz ustawione. Jeśli nie, możesz dodać je shopt -s extglobdo swojego, ~/.bashrca zostanie ono ustawione po uruchomieniu Bash. Po ustawieniu dowolną z tych metod wystarczy wpisać findpolecenie.
Dennis Williamson,
@Dennis: To jest naprawdę bardzo wygodne. Więc jeśli napiszę to, co napisałeś, będzie to wyglądać we wszystkich bieżących plikach / katalogach w miejscu, w którym aktualnie się znajduję?
Amit
Och, to działa jak urok. O wiele łatwiej zapamiętać.
Amit
Czy mógłbyś rozwinąć nieco więcej przy użyciu tej techniki? Co jeśli teraz nie chcę A i D? Jak by to było napisane?
Amit
12

To byłoby -prune- ale jest w tym niewielka sztuczka:

$ find . \( -name D -prune \) -o -name hi.dat

-pruneoznacza „nie szukaj dalej na tej ścieżce”, więc potrzebujesz innej gałęzi dla katalogów innych niż D. ( -ooznacza „lub”.) Aby pominąć także inne ścieżki:

$ find . \( \( -name D -o -name Dminor \) -prune \) -o -name hi.dat
geekozaur
źródło
Cześć geekozaur. Właśnie obniżyłem twoją odpowiedź. Proszę spojrzeć na odpowiedź M. Meglio . Mam nadzieję, że to zmotywuje cię do poprawy odpowiedzi. W takim razie mogę pod głosować twoją odpowiedź ... Pozdrawiam ;-)
olibre
4

Bardziej ogólnym poleceniem znajdowania jest

find -path ./D -prune -o -name hi.dat -print

Zastrzeżenie : -pathtest może jeszcze nie być przenośny / jest częścią standardu POSIX.

Uzasadnienie : w strukturze katalogów jak poniżej

$ find
.
./D
./A
./A/D
./A/D/hi.dat

w porównaniu do

$ find . \( -name D -prune \) -o -name hi.dat
./D
./A/D

wyświetli tylko te pliki, które były rzeczywiście wyszukiwane (jawnie -print) i nie pominie plików w podkatalogach o nazwie D ( -path):

$ find -path ./D -prune -o -name hi.dat -print
./A/D/hi.dat
M. Meglio
źródło
0

Działa pipowanie grep -v,

$ find / -name "*~"|grep -v "/media"

wygląda wszędzie, ale nie w katalogu multimediów

Mick
źródło
Będzie tam wyglądać, ale wyniki zostaną wyrzucone, więc to podejście może być dość nieefektywne, gdy ścieżki do pominięcia zawierają wiele plików i katalogów.
pabouk
W rzeczywistości jest to całkowicie niewłaściwe podejście, ponieważ / media może być podkatalogiem, którego nie chcesz pominąć, ponadto może istnieć (podk) katalog / medial, / median itp., Aw tym rozwiązaniu wyrzuciłbyś wszystkie te przypadki.
jimmij