Byłem zdezorientowany, dlaczego find
komenda drukuje również przycięte katalogi , i kilka innych zawiłych szczegółów na temat tego, jak -prune
działało, ale udało mi się to z kilku przykładów.
Aby uruchomić poniższe przykłady, utwórz następujące katalogi i pliki.
mkdir aa
mkdir bb
touch file1
touch aa/file1
touch bb/file3
Aby utworzyć tę strukturę:
$ tree
.
├── aa
│ └── file1
├── bb
│ └── file3
└── file1
Teraz użyj find, aby wyszukać katalogi o nazwie aa
. Tutaj nie ma problemu.
$ find . -type d -name aa
./aa
Poszukaj wszystkich katalogów innych niż aa, a my otrzymamy bieżący katalog .
i ./bb
, co również ma sens.
$ find . -type d ! -name aa
.
./bb
Jak dotąd tak dobrze, ale kiedy korzystamy -prune
, find zwraca katalog, który przycinamy, co początkowo mnie zdezorientowało, ponieważ spodziewałem się, że zwróci wszystkie inne katalogi, a nie ten, który jest przycinany.
$ find . -type d -name aa -prune
./aa
Powód, dla którego zwraca przycinany katalog, został wyjaśniony nie w -prune
sekcji stron podręcznika, jak wskazano w odpowiedzi Timo , ale w EXPRESSIONS
sekcji:
Jeśli wyrażenie nie zawiera żadnych działań innych niż -prune
,
-print
wykonywane jest na wszystkich plikach, dla których wyrażenie jest prawdziwe.
co oznacza, że ponieważ wyrażenie pasuje do aa
nazwy katalogu, to wyrażenie będzie miało wartość true i zostanie wydrukowane, ponieważ find niejawnie dodaje znak „ -print
na końcu” całego polecenia. Nie doda to -print
jednak, jeśli celowo dodasz akcję -o -print
do końca:
find . -type d -name aa -prune -o -print
.
./file1
./bb
./bb/file3
Tutaj polecenie find NIE dodaje -print
już niejawnego , więc katalog, który przycinamy ( aa
), nie zostanie wydrukowany.
Wreszcie, jeśli dodamy klauzulę, która wyszukuje pliki o wzorcu nazw plików następującym file*
po -o
, musisz umieścić -print
na końcu drugiej klauzuli w następujący sposób:
find . \( -type d -name aa -prune \) -o \( -type f -name 'file*' -print \)
./file1
./bb/file3
Powód, dla którego to działa, jest taki sam: jeśli nie umieścisz -print
w drugiej klauzuli, to ponieważ nie ma innej akcji niż -prune
akcja, find doda -print
automatycznie na KONIEC polecenia, powodując -prune
wydrukowanie klauzuli przycięty katalog:
find . \( \( -type d -name aa -prune \) -o \( -type f -name 'file*' \) \) -print
./aa
./file1
./bb/file3
Ogólnie rzecz biorąc, musisz umieścić -print
polecenie w drugiej klauzuli. Jeśli umieścisz go na środku, tak jak oryginalny plakat, nie będzie działał poprawnie, ponieważ przycinane pliki zostaną wydrukowane natychmiast, a druga klauzula nie będzie miała szansy wybrać plików, które chce:
find . \( -type d -name aa -prune -o -print \) -o \( -type f -name 'file*' \)
.
./file1
./bb
./bb/file3
Niestety, oryginalny plakat źle podał powyższe polecenie, umieszczając go -print
w niewłaściwym miejscu. Mogło to zadziałać w jego konkretnym przypadku, ale nie działa w przypadku ogólnym.
Istnieją tysiące ludzi, którzy mają trudności ze zrozumieniem, jak -prune
działa. find
Strona człowiek powinien być aktualizowany w celu zapobieżenia Niekończąca światową zamieszanie o tym poleceniu.
-print
, w przeciwnym razie domniemanie-print
dotyczy całego warunku