*
มีความหมายพิเศษทั้งเปลือกglobbingตัวอักษร ( "สัญลักษณ์แทน") และเป็นนิพจน์ปกติmetacharacter คุณต้องใช้เวลาทั้งเข้าบัญชี แต่ถ้าคุณพูดgrep
การแสดงออกปกติของคุณแล้วคุณสามารถป้องกันไม่ให้เปลือกจากรักษามันพิเศษและให้แน่ใจว่าจะผ่านมันไปไม่เปลี่ยนแปลง แม้ว่าการจัดเรียงของที่คล้ายกันแนวคิดสิ่งที่หมายถึงเปลือกค่อนข้างแตกต่างจากสิ่งที่มันหมายถึง*
grep
ก่อนอื่นเชลล์จะถือว่า*
เป็นสัญลักษณ์แทน
คุณพูดว่า:
การแสดงออกถูกล้อมรอบด้วยเครื่องหมายคำพูดหรือไม่ไม่ต่างกัน
ขึ้นอยู่กับว่าไฟล์ใดมีอยู่ในไดเรกทอรีใดก็ตามที่คุณเกิดขึ้นเมื่อคุณรันคำสั่ง สำหรับรูปแบบที่มีตัวคั่นไดเรกทอรี/
อาจขึ้นอยู่กับไฟล์ที่มีอยู่ในระบบทั้งหมดของคุณ คุณควรอ้างอิงนิพจน์ปกติสำหรับgrep
- และอัญประกาศเดี่ยวมักจะดีที่สุด - เว้นแต่คุณจะแน่ใจว่าคุณโอเคกับการแปลงที่อาจเกิดขึ้นอย่างน่าประหลาดใจเก้าประเภทเชลล์จะทำงานก่อนที่จะดำเนินการgrep
คำสั่ง
เมื่อเชลล์พบ*
อักขระที่ไม่ได้อ้างถึงมันจะหมายถึง "ศูนย์หรือมากกว่าของอักขระใด ๆ " และแทนที่คำที่มีอยู่ในนั้นด้วยรายการชื่อไฟล์ที่ตรงกับรูปแบบ (ชื่อไฟล์ที่เริ่มต้นด้วยการ.
ได้รับการยกเว้น - ถ้ารูปแบบของคุณเองเริ่มต้นด้วย.
หรือคุณได้กำหนดค่าเปลือกของคุณจะรวมพวกเขาต่อไป.) นี้เป็นที่รู้จักกันglobbing --and ยังโดยชื่อการขยายตัวชื่อไฟล์และการขยายตัวของพา ธ
โดยgrep
ปกติแล้วเอฟเฟ็กต์จะเป็นชื่อไฟล์แรกที่จับคู่เป็นนิพจน์ปกติ - แม้ว่าจะเป็นที่ชัดเจนสำหรับผู้อ่านมนุษย์ว่ามันไม่ได้หมายถึงการแสดงออกปกติ - ในขณะที่ชื่อไฟล์อื่น ๆ ที่ระบุโดยอัตโนมัติจากคุณ glob จะถูกนำมาเป็นไฟล์ที่อยู่ภายในเพื่อค้นหาการแข่งขัน (คุณไม่เห็นรายการ - มันถูกส่งผ่านไปยัง opaquely grep
) คุณแทบไม่ต้องการให้สิ่งนี้เกิดขึ้น
เหตุผลนี้บางครั้งก็ไม่ใช่ปัญหา - และในกรณีของคุณอย่างน้อยที่สุดก็ไม่ใช่ - นั่นคือ*
จะถูกทิ้งให้อยู่คนเดียวถ้าทั้งหมดต่อไปนี้เป็นจริง :
มีไม่มีไฟล์ที่มีชื่อการจับคู่ ... หรือคุณมีคนพิการ globbing ในเปลือกของคุณโดยปกติจะมีหรือเทียบเท่าset -f
set -o noglob
แต่นี่เป็นเรื่องแปลกและคุณอาจจะรู้ว่าคุณทำมัน
คุณกำลังใช้เชลล์ที่มีพฤติกรรมเริ่มต้นที่จะทิ้งไว้*
คนเดียวเมื่อไม่มีชื่อไฟล์ที่ตรงกัน นี่เป็นกรณีใน Bash ซึ่งคุณอาจใช้ แต่ไม่ได้อยู่ในกระสุนสไตล์บอร์นทั้งหมด (พฤติกรรมเริ่มต้นในเชลล์ Zsh ที่เป็นที่นิยมเช่นสำหรับ globs เพื่อ(a) การขยายหรือ(b)ทำให้เกิดข้อผิดพลาด) ... หรือคุณได้เปลี่ยนพฤติกรรมนี้ของเชลล์ของคุณ - วิธีการทำแตกต่างกันไป ข้ามเปลือกหอย
ท่านยังไม่ได้เป็นอย่างอื่นบอกว่าเปลือกของคุณจะอนุญาตให้ globs ถูกแทนที่ด้วยอะไรเมื่อไม่มีไฟล์ที่ตรงกันหรือที่จะล้มเหลวด้วยข้อผิดพลาดในสถานการณ์เช่นนี้ ใน Bash ที่จะทำโดยเปิดใช้งานตัวเลือกnullglob
หรือfailglob
เปลือกตามลำดับ
บางครั้งคุณสามารถพึ่งพา # 2 และ # 3 แต่คุณสามารถพึ่งพา # 1 ได้ grep
คำสั่งที่มีรูปแบบ unquoted ที่ทำงานตอนนี้อาจหยุดการทำงานเมื่อคุณมีไฟล์ที่แตกต่างกันหรือเมื่อคุณเรียกใช้งานจากสถานที่ที่แตกต่างกัน พูดการแสดงออกปกติของคุณและปัญหาจะหายไป
จากนั้นgrep
ถือว่าคำสั่ง*
เป็นปริมาณ
คำตอบอื่น ๆ - เช่นที่โดย Sergiy Kolodyazhnyyและโดย kos --also ยังได้กล่าวถึงประเด็นนี้ของคำถามนี้ในรูปแบบที่แตกต่างกันบ้าง ดังนั้นฉันขอแนะนำให้ผู้ที่ยังไม่ได้อ่านให้ทำก่อนหรือหลังอ่านคำตอบที่เหลือ
สมมติว่า*
ไม่ให้มันไป grep - ซึ่งอ้างควร ensure-- grep
แล้วจะให้หมายความว่ารายการที่นำหน้ามันอาจเกิดขึ้นจำนวนครั้งใดมากกว่าที่มีจะเกิดขึ้นเพียงครั้งเดียวเท่านั้น มันอาจยังเกิดขึ้นอีกครั้ง หรืออาจจะไม่ปรากฏเลย หรืออาจจะซ้ำ ข้อความที่เหมาะกับความเป็นไปได้เหล่านั้นจะถูกจับคู่
ฉันหมายถึงอะไรโดย "รายการ"
เดียวตัวละคร เนื่องจากb
ตรงกับตัวอักษรb
, b*
ตรงกับศูนย์หรือมากกว่าb
s จึงab*c
ตรงac
, abc
, abbc
, abbbc
ฯลฯ
ในทำนองเดียวกันตั้งแต่.
ตรงกับตัวอักษรใด ๆ , .*
ตรงกับศูนย์หรือมากกว่าตัวอักษร1จึงa.*c
ไม้ขีดไฟac
, akc
, ahjglhdfjkdlgjdfkshlgc
แม้acccccchjckhcc
ฯลฯหรือ
ตัวละครคลาส นับตั้งแต่[xy]
การแข่งขันx
หรือy
, [xy]*
การแข่งขันศูนย์ตัวอักษรหรือมากกว่าที่แต่ละคนเป็นอย่างใดอย่างหนึ่งx
หรือy
จึงp[xy]*q
ตรงpq
, pxq
, pyq
, pxxq
, pxyq
, pyxq
, pyyq
, pxxxq
, pxxyq
ฯลฯ
นี้ยังใช้กับรูปแบบการจดชวเลขของตัวละครคลาสชอบ\w
, \W
, และ\s
\S
เนื่องจาก\w
ตรงกับอักขระคำใด ๆ จึงจับคู่อักขระ\w*
ศูนย์หรือมากกว่านั้น หรือ
กลุ่ม นับตั้งแต่\(bar\)
การแข่งขันbar
, \(bar\)*
การแข่งขันเป็นศูนย์หรือมากกว่าbar
s จึงfoo\(bar\)*baz
ตรงfoobaz
, foobarbaz
, foobarbarbaz
, foobarbarbarbaz
ฯลฯ
ด้วย-E
หรือ-P
เลือกgrep
ปฏิบัติต่อการแสดงออกปกติของคุณเป็นEREหรือPCREตามลำดับมากกว่าที่จะเป็นBREแล้วกลุ่มถูกล้อมรอบด้วย(
)
แทน\(
\)
ดังนั้นแล้วคุณต้องการใช้(bar)
แทน\(bar\)
และแทนfoo(bar)baz
foo\(bar\)baz
man grep
ให้คำอธิบายที่สมเหตุสมผลที่สามารถเข้าถึงได้ของ BRE และไวยากรณ์ ERE ในตอนท้ายรวมถึงการแสดงรายการตัวเลือกบรรทัดคำสั่งทั้งหมดที่grep
ยอมรับได้ในตอนเริ่มต้น ฉันแนะนำหน้าคู่มือนั้นเป็นแหล่งข้อมูลและยังรวมถึงเอกสาร GNU Grepและเว็บไซต์กวดวิชา / ข้อมูลอ้างอิง (ซึ่งฉันได้เชื่อมโยงกับหน้าเว็บหลายหน้าบน)
สำหรับการทดสอบและการเรียนรู้grep
ฉันแนะนำให้เรียกมันด้วยรูปแบบ แต่ไม่มีชื่อไฟล์ จากนั้นจะรับอินพุตจากเทอร์มินัลของคุณ ใส่บรรทัด; บรรทัดที่ถูกสะท้อนกลับมาหาคุณคือบรรทัดที่มีข้อความที่ตรงกับรูปแบบของคุณ หากต้องการออกให้กดCtrl+ Dที่จุดเริ่มต้นของบรรทัดซึ่งสัญญาณจะสิ้นสุดการป้อนข้อมูล (หรือคุณสามารถกดCtrl+ Cเช่นเดียวกับโปรแกรมบรรทัดคำสั่งส่วนใหญ่) ตัวอย่างเช่น:
grep 'This.*String'
หากคุณใช้--color
แฟล็กgrep
จะเน้นส่วนเฉพาะของบรรทัดที่ตรงกับนิพจน์ปกติของคุณซึ่งมีประโยชน์มากสำหรับทั้งการหาว่านิพจน์ปกติทำอะไรและค้นหาสิ่งที่คุณกำลังมองหาเมื่อคุณทำ โดยค่าเริ่มต้นผู้ใช้ Ubuntu มีนามแฝง Bash ที่ทำให้เกิดgrep --color=auto
การเรียกใช้ซึ่งเพียงพอสำหรับวัตถุประสงค์นี้เมื่อคุณเรียกใช้grep
จากบรรทัดคำสั่งดังนั้นคุณอาจไม่จำเป็นต้องผ่าน--color
ด้วยตนเอง
1 ดังนั้น.*
ในการแสดงออกปกติหมาย*
ถึงความหมายในเปลือกกลม อย่างไรก็ตามความแตกต่างคือgrep
พิมพ์บรรทัดที่มีการจับคู่ของคุณที่ใดก็ได้โดยอัตโนมัติดังนั้นโดยทั่วไปไม่จำเป็นต้องมี.*
ที่จุดเริ่มต้นหรือจุดสิ้นสุดของการแสดงออกปกติ
* != any number of unknown characters
. อ่านเอกสาร)