„Find: ścieżki muszą poprzedzać wyrażenie”. Jak określić wyszukiwanie rekurencyjne, które również znajdzie pliki w bieżącym katalogu?

235

Trudno mi znaleźć szukanie dopasowań w bieżącym katalogu, a także w jego podkatalogach.

Po uruchomieniu find *test.cdaje mi tylko dopasowania w bieżącym katalogu. (nie przegląda podkatalogów)

Gdybym spróbował find . -name *test.c, oczekiwałbym takich samych wyników, ale zamiast tego daje mi tylko te dopasowania, które są w podkatalogu. Kiedy w katalogu roboczym są pliki, które powinny pasować, daje mi to:find: paths must precede expression: mytest.c

Co oznacza ten błąd i jak mogę uzyskać dopasowania zarówno z bieżącego katalogu, jak i jego podkatalogów?

Chris Finley
źródło
4
dla przypomnienia, findod msysGit może rzucić ten błąd, chyba że otaczają wzór z cytatów: find . -name "*test.c". (Jeśli wolisz, aby był inny niż Windows find.exei użyj go z cmd)
n611x007

Odpowiedzi:

393

Spróbuj wpisać go w cudzysłów - napotkasz rozszerzenie wieloznaczne powłoki, więc to, co faktycznie podajesz, będzie wyglądać:

find . -name bobtest.c cattest.c snowtest.c

... powodując błąd składniowy. Spróbuj więc zamiast tego:

find . -name '*test.c'

Zwróć uwagę na pojedyncze cudzysłowy wokół wyrażenia pliku - zatrzymają one rozszerzanie powłoki przez symbole wieloznaczne.

Chris J
źródło
15
Przykładowo, możesz zobaczyć, co się stanie, jeśli to zrobisz echo *test.c... wynikiem nie będzie echo rozwinięcia symbolu wieloznacznego, ale sama powłoka. Prosta lekcja jest taka, że ​​jeśli używasz symboli wieloznacznych, zacytuj specyfikację pliku :-)
Chris J
Dzięki za pomoc w tym wariancie. Próbowałem, find . -type f -printf ‘%TY-%Tm-%Td %TT %p\n’jak znaleziono w Internecie, i napotkałem „ścieżki muszą poprzedzać wyrażenie”. Problem polegał na tym, że znaki cudzysłowu były zbyt „inteligentne”. Ponownie wpisałem polecenie, powodując zamianę cytatów, i zadziałało.
Smandoli,
2
Z jakiegoś powodu pojedyncze cytaty mi nie działały. Musiałem użyć podwójnych cudzysłowów. ¯ \ _ (ツ) _ / ¯
Planky
pojedyncze cudzysłowy przy wyszukiwaniu symboli wieloznacznych działały z Busybox i GNU find- jeśli używasz symboli wieloznacznych *.$variable, potrzebujesz podwójnych cudzysłowów.
Stuart Cardall
@Planky: Wstawiam: find, -name 'write.lock' w pliku skryptu powłoki, ale ma ten komunikat o błędzie. Ale jeśli piszę w konsoli, to działa. Czy ktoś wie dlaczego?
Scott Chu,
28

To, co się dzieje, polega na tym, że powłoka rozwija „* test.c” do listy plików. Spróbuj uciec gwiazdkę jako:

find . -name \*test.c
Jim Garrison
źródło
#gitbash to było dla mnie rozwiązanie z git bash na Windowsie, nawet gdy cytuję WZÓRfind . -name '*txt'
inny ben
17

Spróbuj wpisać to w cudzysłów:

find . -name '*test.c'
rkulla
źródło
13

Z podręcznika znajdź:

NON-BUGS         

   Operator precedence surprises
   The command find . -name afile -o -name bfile -print will never print
   afile because this is actually equivalent to find . -name afile -o \(
   -name bfile -a -print \).  Remember that the precedence of -a is
   higher than that of -o and when there is no operator specified
   between tests, -a is assumed.

   “paths must precede expression” error message
   $ find . -name *.c -print
   find: paths must precede expression
   Usage: find [-H] [-L] [-P] [-Olevel] [-D ... [path...] [expression]

   This happens because *.c has been expanded by the shell resulting in
   find actually receiving a command line like this:
   find . -name frcode.c locate.c word_io.c -print
   That command is of course not going to work.  Instead of doing things
   this way, you should enclose the pattern in quotes or escape the
   wildcard:
   $ find . -name '*.c' -print
   $ find . -name \*.c -print
Nick Constantine
źródło
0

Natknąłem się na to pytanie, gdy próbowałem znaleźć wiele nazw plików, których nie mogłem połączyć w wyrażenie regularne, jak opisano w odpowiedzi @Chris J, oto, co zadziałało dla mnie

find . -name one.pdf -o -name two.txt -o -name anotherone.jpg

-olub -orjest logiczne LUB. Aby uzyskać więcej informacji, zobacz Znajdowanie plików na Gnu.org .

Uruchomiłem to na CygWin.

Szczęśliwe miasto
źródło
-1

W moim przypadku brakowało mi /podążania ścieżką.

find /var/opt/gitlab/backups/ -name *.tar
Vikash Singh
źródło
1
Końcowe /nie jest wymagane.
melpomene