“ find: พา ธ ต้องนำหน้านิพจน์:” ฉันจะระบุการค้นหาแบบเรียกซ้ำที่ค้นหาไฟล์ในไดเรกทอรีปัจจุบันได้อย่างไร


235

ฉันมีปัญหาในการค้นหาเพื่อค้นหาการจับคู่ในไดเรกทอรีปัจจุบันเช่นเดียวกับไดเรกทอรีย่อย

เมื่อฉันเรียกใช้find *test.cจะให้เฉพาะรายการที่ตรงกันในไดเรกทอรีปัจจุบัน (ไม่ดูในไดเรกทอรีย่อย)

หากฉันลองfind . -name *test.cฉันจะคาดหวังผลลัพธ์เดียวกัน แต่จะให้เฉพาะการจับคู่ที่อยู่ในไดเรกทอรีย่อยแทน เมื่อมีไฟล์ที่ควรจะตรงกับในไดเร็คทอรี่สำหรับใช้ทำงานมันจะทำให้ฉัน:find: paths must precede expression: mytest.c

ข้อผิดพลาดนี้หมายถึงอะไรและฉันจะได้รับการแข่งขันจากทั้งไดเรกทอรีปัจจุบันและไดเรกทอรีย่อยได้อย่างไร


4
สำหรับบันทึกfindของmsysgitfind . -name "*test.c"อาจโยนความผิดพลาดนี้จนกว่าคุณจะล้อมรอบรูปแบบด้วยคำพูด: (ในกรณีที่คุณเลือกที่จะชอบมันมากกว่า Windows ที่แตกต่างกันfind.exeและการใช้งานจาก cmd)
n611x007

คำตอบ:


393

ลองใส่ไว้ในเครื่องหมายอัญประกาศ - คุณกำลังใช้ส่วนขยายของสัญลักษณ์แทนของเชลล์ดังนั้นสิ่งที่คุณส่งผ่านการค้นหาจะมีลักษณะดังนี้:

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

... ทำให้เกิดข้อผิดพลาดทางไวยากรณ์ ลองใช้วิธีนี้แทน:

find . -name '*test.c'

สังเกตเครื่องหมายคำพูดเดี่ยวรอบ ๆ นิพจน์ไฟล์ของคุณ - สิ่งเหล่านี้จะหยุดเชลล์ (ทุบตี) ขยาย wildcard ของคุณ


15
จากตัวอย่างคุณสามารถเห็นสิ่งที่เกิดขึ้นถ้าคุณทำecho *test.c... ผลลัพธ์จะไม่ได้สะท้อนการขยายตัวสัญลักษณ์ แต่เปลือกตัวเอง บทเรียนง่าย ๆ คือถ้าคุณใช้ไวลด์การ์ดให้พูดถึง filespec :-)
Chris J

ขอบคุณที่ช่วยฉันด้วยตัวแปรนี้ ฉันลองfind . -type f -printf ‘%TY-%Tm-%Td %TT %p\n’ตามที่พบในเว็บและพบกับ "พา ธ ต้องนำหน้านิพจน์" ปัญหาคือเครื่องหมายคำพูดนั้น "ฉลาดเกินไป" ฉันพิมพ์คำสั่งอีกครั้งทำให้ราคาถูกแทนที่และมันก็วิ่ง
Smandoli

2
ด้วยเหตุผลบางอย่างราคาเดียวไม่ได้สำหรับฉัน ฉันต้องใช้เครื่องหมายคำพูดคู่ ¯ \ _ (ツ) _ / ¯
Planky

เครื่องหมายคำพูดเดี่ยวสำหรับการค้นหาไวด์การ์ดที่ทำงานกับ Busybox & GNU find- หากใช้ไวด์การ์ด*.$variableคุณต้องใช้เครื่องหมายคำพูด
Stuart Cardall

@Planky: ฉันใส่: find, -name 'write.lock' ในไฟล์เชลล์สคริปต์ แต่มีข้อความแสดงข้อผิดพลาดนี้ แต่ถ้าฉันพิมพ์ในคอนโซลมันใช้งานได้ ใครรู้ว่าทำไม
Scott Chu

28

สิ่งที่เกิดขึ้นคือเชลล์กำลังขยาย "* test.c" ลงในรายการไฟล์ ลองหนีเครื่องหมายดอกจันเป็น:

find . -name \*test.c

#gitbash นี่เป็นวิธีแก้ปัญหาสำหรับฉันเมื่อใช้ git bash บน windows แม้ว่าจะอ้างถึงรูปแบบfind . -name '*txt'
ben


13

จากค้นหาคู่มือ:

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

0

ฉันเจอคำถามนี้เมื่อฉันพยายามค้นหาหลายชื่อไฟล์ที่ฉันไม่สามารถรวมเป็นนิพจน์ทั่วไปตามที่อธิบายไว้ในคำตอบของ @Chris J นี่คือสิ่งที่ทำงานให้ฉัน

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

-oหรือ-orเป็นตรรกะหรือ ดูการค้นหาไฟล์ใน Gnu.orgสำหรับข้อมูลเพิ่มเติม

ฉันใช้งาน CygWin อยู่


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.