การตีความนิพจน์ทั่วไปโดยใช้ find ใน Linux confusion


1

ฉันพยายามใช้findคำสั่งและพบบทความที่http://www.linux.ie/newusers/beginners-linux-guide/find.phpซึ่งระบุว่า:

อักขระไวด์การ์ดจะถูก Escape ด้วยเครื่องหมายทับเพื่อให้ BASH ส่งเครื่องหมายดอกจันตามตัวอักษรไปยังยูทิลิตี find เป็นอาร์กิวเมนต์แทนการดำเนินการขยายชื่อไฟล์และส่งผ่านไฟล์จำนวนเท่าใดก็ได้ในรูปแบบอาร์กิวเมนต์

find . -name up\*สำหรับคำสั่ง

เป็นใหม่กับโลกของลินุกซ์ที่ฉันไม่เข้าใจวิธีการใช้เครื่องหมายที่มีความหมายที่จะหลบหนีอักขระ meta ถูกตีความและผลตอบแทนราวกับว่ามันจะถูกส่งผ่านไปยัง* findหมายความว่าถ้าฉันใช้-nameตัวเลือกที่ฉันต้องใช้แบ็กสแลชเพื่อส่งผ่านตัวแทนและถ้าฉันไม่ใช้-nameฉันไม่ต้องใช้แบ็กสแลช? มีการใช้แบ็กสแลชเพื่อที่เชลล์ bash จะไม่พยายามขยายหรือไม่?

คำตอบ:


1

ระวังให้ดีว่าคุณกำลังใช้คำว่า "regular expression" ค่อนข้างหลวม .. สิ่งที่คุณกำลังทำอยู่ในfind -nameตัวเลือกนั้นค่อนข้างใกล้เคียงกับพฤติกรรมของshell glob... ในทางกลับกันfind -regexตัวเลือกนี้ใช้การค้นหาแบบ expression ปกติ คุณสามารถเลือกรูปแบบของ regex ที่จะใช้ผ่านตัวเลือก -regextyp .. ตัวเลือกประเภทที่ใช้ในปัจจุบันคือ: emacs (นี่คือค่าเริ่มต้น), posix-awk, posix-basic, posix-egrep และ posix-Extended ...

วิธีจัดการกับแบ็กสแลชและดอกจัน ฯลฯ อาจแตกต่างกันไปขึ้นอยู่กับสิ่งที่คุณต้องการจะทำ หากคุณต้องการfind -nameที่จะต้องพิจารณาก็ดอกจันเป็นอักขระตัวแทนแล้วคุณจะต้องให้แน่ใจว่าจะไม่หลบหนีเมื่อfindจริงอ่านรูปแบบจากบรรทัดคำสั่ง

เพื่อให้แน่ใจว่าการ ค้นหาได้มาในรูปแบบที่ไม่ใช้ค่า Escape คุณต้องป้องกันเชลล์ (โดยทั่วไปคือทุบตี ) จากการทำงานของการขยายตัวของเชลล์ * (มีประสิทธิภาพมาก) บนเครื่องหมายดอกจันของคุณ ... เพื่อปกป้องมันคุณต้อง หนีออกจากระดับบรรทัดคำสั่ง เช่น. "หลบหนี" ในสายตาของกระสุน) .. แนวคิดหลัก ณ จุดนี้คือ"ป้องกัน" ...

คุณสามารถป้องกันเครื่องหมายดอกจันจากเชลล์ได้สามวิธี:

  • ใช้'เครื่องหมายคำพูดเดี่ยว'
  • ใช้"เครื่องหมายคำพูดคู่"
  • ใช้\แบ็กสแลช (และไม่มีเครื่องหมายคำพูด)

ดังนั้นfindเพื่อดูว่าเครื่องหมายดอกจันของคุณเป็นไวลด์การ์ดวิธีการ "ป้องกัน" ใด ๆ ต่อไปนี้จะใช้งานได้

  • find -name up'*'
  • find -name up"*"
  • find -name up\*
  • find -name 'up*'
  • find -name "up*"
  • find -name "up"\*

โปรดทราบว่าเชลล์จะไม่ขยายตัวในสิ่งใดใน'เครื่องหมายคำพูดเดี่ยว'... "เครื่องหมายคำพูดคู่"เป็นเรื่องราวที่แตกต่าง ..


หนึ่งในคำตอบที่ดีที่สุด ยกโทษให้ n00bness ของฉัน แต่กำลังสับสนโดยคำสั่งและตามมาด้วยthen you need to ensure that it is NOT escaped when find actually reads the pattern from the command line. สับสนต่อไปโดยTo protect it you MUST escape it at the command-line level Note that the shell will never perform expansion on anything in 'single quotes' ... "double quotes" are a different story.ดังนั้นเมื่อดูที่คำแถลงแรกที่คุณพูดถึงมันจะต้องไม่หนี
PeanutsMonkey

find . -name up\*แต่ตามที่คุณกล่าวถึงการหลบหนีในระดับบรรทัดคำสั่งซึ่งผมถือว่าหมายถึงภายในคำสั่งของตัวเองเช่น นี่คือการรวมกันโดยคำสั่งสุดท้ายที่คุณพูดถึงการขยายตัวไม่ได้ทำอะไรกับคำพูดเดียว คุณหมายถึงว่า bash shell ไม่ได้ขยายอะไรด้วยเครื่องหมายคำพูดเดี่ยว แต่findคำสั่งทำหรือไม่?
PeanutsMonkey

1
ใช่ 'ในเครื่องหมายคำพูดเดี่ยว' หมายถึงshellคือ บรรทัดคำสั่ง แอปที่เรียกว่า (เช่น 'ค้นหา') มีอิสระในการประมวลผลเครื่องหมายดอกจัน (ภายใน) ตามที่เห็นสมควร การfindใช้เครื่องหมายดอกจันอย่างง่าย ๆ ซึ่งเป็นสิ่งที่คุณต้องการในสถานการณ์นี้คือประเภทของสิ่งที่คุณต้องแจ้งเตือนเสมอ bash shell สามารถทำสิ่งที่น่าสนใจล่วงหน้าได้ในบรรทัดคำสั่ง แต่คุณจำเป็นต้องจัดการมัน .. Quotes และ backslash เป็นกลไกการควบคุม find -name up\*และ'up*'ป้องกันเครื่องหมายดอกจันจากเปลือก หากไม่ได้รับการป้องกันมันจะขยายไปยังชื่อไฟล์ที่ตรงกัน (หลายรายการ)
Peter.O

... เมื่ออยู่ในfindโดเมนแล้วเครื่องหมายดอกจันจะเป็นเครื่องหมายดอกจันที่แท้จริงอีกครั้ง (นั่นคือมันจะไม่ถูกหลบหนี) ... วิธีการ "ป้องกัน" ของบรรทัดคำสั่ง bash (คำพูด / แบ็กสแลช) จะถูกทิ้งโดย bash; พวกเขาเป็นเพียงมีเป็นตัวชี้วัดที่จะทุบตีเป็นวิธีการจัดการกับการขยายบรรทัดคำสั่งของมัน...มี 6 หมวดหมู่ของการขยายตัวเปลือก: 1 การขยายตัวรั้ง ที่ 2 การขยายตัวของตัวหนอน3 . การขยายตัวพารามิเตอร์4 การขยายตัว5 . การแยกคำ6 . การขยายชื่อพา ธ
Peter.O

ดังนั้นถ้าฉันไม่ได้หลบเลี่ยงอักขระเมตาเช่น*นี้หมายความว่าคำสั่งfind . -name up*จะถูกตีความโดยทั้ง bash shell และfind? ประการที่สองเมื่อคุณพูดว่าทิ้งคุณหมายถึงอะไรกันแน่? สุดท้ายนี้คุณอยากทราบรายละเอียดเกี่ยวกับการขยายตัวของเชลล์ทั้ง 6 หมวดหมู่หรือไม่?
PeanutsMonkey

2

สิ่งที่คุณหายไปคือเปลือกและค้นหาส่วนขยาย * คุณต้องการค้นหาเพื่อขยายดังนั้นคุณต้องซ่อนมันจากเปลือก

คุณกำลังมองหาไฟล์ทั้งหมดที่อยู่นอกไดเรกทอรีปัจจุบันซึ่งชื่อขึ้นต้นด้วย "on" ใช่ไหม? หากคุณปล่อยให้เชลล์ขยายตัว * คุณจะไม่ได้รับสิ่งนั้น สมมติว่าไดเรกทอรีปัจจุบันของคุณมีไฟล์ "ขึ้น" และ "ยก" จากนั้นเชลล์จะเปลี่ยนคำสั่งของคุณเป็น

find . -name upward uplift

ซึ่งเป็นไวยากรณ์ที่ไม่ดีสำหรับการค้นหา หากไม่มีไฟล์ที่ตรงกันเชลล์จะปล่อยให้อาร์กิวเมนต์อยู่คนเดียว แต่เป็นการดีที่จะใช้คำสั่งที่ใช้งานได้ดีโดยไม่คำนึงถึงรายละเอียดเช่นนั้น

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