Uruchamiam następujące polecenie, ale nie jest ono wykonywane rekurencyjnie:
find . -name *.java
Wiem, że dalej w bieżącym katalogu znajdują się pliki java, ale find
wykonuje tylko w bieżącym katalogu. Używam OS X 10.9.
Odpowiedź
Problem polega na tym, że nie zacytowałeś swojego -name
. Zamiast tego zrób to:
find . -name "*.java"
Wyjaśnienie
Bez cudzysłowów, powłoka interpretuje *.java
jako wzorzec glob i rozszerza go na dowolne nazwy plików pasujące do globu przed przekazaniem go do find
. W ten sposób, jeśli masz, powiedzmy, foo.java
w bieżącym katalogu, find
„rzeczywista linia poleceń wyglądałaby następująco:
find . -name foo.java
, który oczywiście wyświetlałby plik tylko w bieżącym katalogu (chyba że masz podobnie nazwane pliki dalej w dół drzewa).
Cytowanie zapobiega rozwijaniu globów i przekazuje wiersz poleceń do find
tak jak jest.
Nawiasem mówiąc, jeśli nie udało się dopasować globu (brak plików *.java
w bieżącym katalogu tory), możesz uzyskać jedno z dwóch zachowań, w zależności od tego, jak Twoja powłoka jest skonfigurowana do obsługi niedopasowanych globów (jest to regulowane przez opcję nullglob
w Bash, na przykład ):
- Jeśli glob, który nie pasuje, nie jest rozszerzany przez powłokę,
find
będzie (przypadkowo, pamiętajcie) wykazywać poprawne zachowanie. - Jeśli glob, który nie pasuje, jest rozwijany przez powłokę do pustego ciągu,
find
będzie narzekał, że brakuje w nim argumentu do-name
.
Odpowiedź
Miałem podobną sytuację, w której otaczałem -name wartość w cudzysłowie, ale nadal nie otrzymałem wszystkich wyników wyszukiwania, na które liczyłem. Przypuszczałem, że dzieje się tak z powodu linków symbolicznych i na pewno tak było. Jeśli chcesz wymusić wyszukiwanie przez linki symboliczne, możesz zmodyfikować polecenie w następujący sposób:
find -L . -name "*.java"
Komentarze
Odpowiedź
Ucieknij z *
find . -name \*.java
-follow
to bardziej czytelny synonim-L
, o ile umieścisz go przed innymi parametrami.