"Find: paths harus mendahului ekspresi:" Bagaimana cara menentukan pencarian rekursif yang juga menemukan file dalam direktori saat ini?

235

Saya mengalami kesulitan mencari untuk menemukan kecocokan di direktori saat ini serta subdirektori.

Ketika saya menjalankannya find *test.chanya memberi saya kecocokan di direktori saat ini. (tidak melihat dalam subdirektori)

Jika saya mencoba, find . -name *test.csaya akan mengharapkan hasil yang sama, tetapi itu hanya memberi saya kecocokan yang ada di subdirektori. Ketika ada file yang harus cocok dengan direktori kerja, itu memberi saya:find: paths must precede expression: mytest.c

Apa artinya kesalahan ini, dan bagaimana saya bisa mendapatkan kecocokan dari direktori saat ini dan subdirektori?

Chris Finley
sumber
4
untuk catatan, finddari msysgit mungkin melemparkan kesalahan ini kecuali jika Anda mengelilingi pola dengan kutipan: find . -name "*test.c". (Jika Anda memilih untuk lebih suka Windows berbeda find.exedan menggunakan dari cmd)
n611x007

Jawaban:

393

Coba letakkan dalam tanda kutip - Anda berlari ke ekspansi wildcard shell, sehingga apa yang sebenarnya Anda lewati untuk menemukan akan terlihat seperti:

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

... menyebabkan kesalahan sintaksis. Jadi cobalah ini sebagai gantinya:

find . -name '*test.c'

Perhatikan tanda kutip tunggal di sekitar ekspresi file Anda - ini akan menghentikan shell (bash) memperluas wildcard Anda.

Chris J
sumber
15
Sebagai contoh, Anda dapat melihat apa yang terjadi jika Anda melakukannya echo *test.c... hasilnya tidak akan gema memperluas wildcard, tetapi shell itu sendiri. Pelajaran sederhana adalah jika Anda menggunakan wildcard, kutip filespec :-)
Chris J
Terima kasih telah membantu saya dengan VARIAN ini. Saya mencoba find . -type f -printf ‘%TY-%Tm-%Td %TT %p\n’seperti yang ditemukan di web, dan bertemu dengan "jalan harus mendahului ekspresi". Masalahnya adalah tanda kutip terlalu "pintar". Saya mengetik ulang perintah, menyebabkan tanda kutip diganti, dan itu berlari.
Smandoli
2
Untuk beberapa alasan, satu kutipan tidak berfungsi untuk saya. Saya harus menggunakan tanda kutip ganda. ¯ \ _ (ツ) _ / ¯
Planky
Kutipan tunggal untuk pencarian wildcard bekerja dengan Busybox & GNU find- jika menggunakan wildcard *.$variableAnda perlu tanda kutip ganda.
Stuart Cardall
@ Planky: Saya memasukkan: find, -name 'write.lock' dalam file skrip shell tetapi ada pesan kesalahan ini. Tetapi jika saya mengetikkan konsol, itu berfungsi. Adakah yang tahu kenapa?
Scott Chu
28

Yang terjadi adalah shell memperluas "* test.c" ke daftar file. Coba lepaskan tanda bintang sebagai:

find . -name \*test.c
Jim Garrison
sumber
#gitbash ini adalah solusi untuk saya dengan git bash di windows, bahkan ketika mengutip POLAfind . -name '*txt'
ben yang berbeda
17

Coba masukkan dalam tanda kutip:

find . -name '*test.c'
rkulla
sumber
13

Dari cari manual:

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
sumber
0

Saya menemukan pertanyaan ini ketika saya mencoba untuk menemukan beberapa nama file yang tidak dapat saya gabungkan menjadi ekspresi reguler seperti yang dijelaskan dalam jawaban @ Chris J, inilah yang bekerja untuk saya

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

-oatau -orlogis ATAU. Lihat Menemukan File di Gnu.org untuk informasi lebih lanjut.

Saya menjalankan ini di CygWin.

HappyTown
sumber
-1

Dalam kasus saya, saya kehilangan /jejak di jalur.

find /var/opt/gitlab/backups/ -name *.tar
Vikash Singh
sumber
1
Trailing /tidak diperlukan.
melpomene