โปรแกรมการศึกษา GREP และนิพจน์ทั่วไป การใช้นิพจน์ทั่วไป (regex) ใน Linux ตารางนิพจน์ทั่วไป grep

ยูทิลิตี้ grep เป็นเครื่องมือค้นหาและกรองที่ทรงพลังมาก ข้อมูลข้อความ. บทความนี้แสดงตัวอย่างการใช้งานหลายประการที่จะช่วยให้คุณชื่นชมความสามารถของมัน
การใช้งานหลักของ grep คือการค้นหาคำหรือวลีในไฟล์และเอาต์พุตสตรีม คุณสามารถค้นหาโดยพิมพ์คำค้นหาและพื้นที่ค้นหา (ไฟล์) ที่บรรทัดคำสั่ง
ตัวอย่างเช่น หากต้องการค้นหาสตริง “needle” ในไฟล์ hystack.txt ให้ใช้คำสั่งต่อไปนี้:

$ grep เข็ม haystack.txt

ด้วยเหตุนี้ grep จะแสดงเข็มทั้งหมดที่พบในเนื้อหาของไฟล์ haystack.txt สิ่งสำคัญที่ควรทราบคือในกรณีนี้ grep กำลังมองหาชุดอักขระ ไม่ใช่คำ ตัวอย่างเช่น สตริงที่มีคำว่า "needless" และคำอื่นๆ ที่มีลำดับ "needle" จะปรากฏขึ้น


หากต้องการบอก grep ว่าคุณกำลังมองหาคำที่เฉพาะเจาะจง ให้ใช้สวิตช์ -w ปุ่มนี้จะจำกัดการค้นหาเฉพาะคำที่ระบุเท่านั้น คำคือแบบสอบถามที่คั่นทั้งสองด้านด้วยช่องว่าง เครื่องหมายวรรคตอน หรือการขึ้นบรรทัดใหม่

$ grep -w เข็มกองหญ้าแห้ง.txt

ไม่จำเป็นต้องจำกัดการค้นหาให้เหลือเพียงไฟล์เดียว grep สามารถค้นหาข้ามกลุ่มของไฟล์ได้ และผลการค้นหาจะระบุไฟล์ที่พบรายการที่ตรงกัน สวิตช์ -n จะเพิ่มหมายเลขบรรทัดที่พบรายการที่ตรงกัน และสวิตช์ -r จะทำให้คุณสามารถค้นหาแบบเรียกซ้ำได้ สะดวกมากเมื่อค้นหาไฟล์ด้วยซอร์สโค้ดของโปรแกรม

$ grep -rnw function_name /home/www/dev/myprogram/

ชื่อไฟล์จะแสดงก่อนการแข่งขันแต่ละครั้ง หากคุณต้องการซ่อนชื่อไฟล์ ให้ใช้สวิตช์ -h ในทางกลับกัน หากคุณต้องการเพียงชื่อไฟล์ ให้ระบุสวิตช์ -l
ในตัวอย่างต่อไปนี้ เราจะค้นหา URL ในไฟล์บันทึกของ IRC และแสดงรายการที่ตรงกัน 10 รายการล่าสุด

$ grep -wo http://.* channel.log | หาง

ตัวเลือก -o บอกให้ grep พิมพ์เฉพาะรูปแบบที่ตรงกัน แทนที่จะพิมพ์ทั้งบรรทัด เมื่อใช้ไปป์ เราจะเปลี่ยนเส้นทางเอาต์พุตของ grep ไปยังคำสั่ง tail ซึ่งโดยค่าเริ่มต้นจะส่งออก 10 บรรทัดสุดท้าย
ตอนนี้เราจะนับจำนวนข้อความที่ผู้ใช้บางรายส่งไปยังช่อง irc เช่น ข้อความทั้งหมดที่ฉันส่งจากบ้านและที่ทำงาน ชื่อเล่นต่างกัน ที่บ้านฉันใช้ชื่อเล่น user_at_home และที่ทำงาน user_at_work

$ grep -c "^user_at_(บ้าน|ที่ทำงาน)" channel.log

เมื่อใช้ตัวเลือก -c grep จะพิมพ์เฉพาะจำนวนรายการที่ตรงกันที่พบ ไม่ใช่รายการที่ตรงกัน สตริงการค้นหาอยู่ในเครื่องหมายคำพูดเนื่องจากมีอักขระพิเศษที่เชลล์สามารถรับรู้ได้ว่าเป็นอักขระควบคุม โปรดทราบว่าเครื่องหมายคำพูดไม่รวมอยู่ในรูปแบบการค้นหา แบ็กสแลช "" ใช้เพื่อหลีกอักขระพิเศษ
มาค้นหาข้อความจากคนชอบ “กรี๊ด” ในช่องกันดีกว่า คำว่า "scream" หมายถึงข้อความที่เขียนด้วยรูปแบบสีบลอนด์ โดยใช้ตัวพิมพ์ใหญ่ทั้งหมด หากต้องการแยกคำย่อแบบสุ่มออกจากการค้นหา เราจะค้นหาคำที่มีอักขระตั้งแต่ห้าตัวขึ้นไป:

$ grep -w "+(5,)" channel.log

สำหรับคำอธิบายโดยละเอียดเพิ่มเติม คุณสามารถดูได้ที่หน้า grep man
ตัวอย่างเพิ่มเติมบางส่วน:

# grep root /etc/passwd root:x:0:0:root:/root:/bin/bash ตัวดำเนินการ:x:11:0:operator:/root:/sbin/nologin

แสดงบรรทัดจากไฟล์ /etc/passwd ที่มีสตริง root

# grep -n root /etc/passwd 1:root:x:0:0:root:/root:/bin/bash 12:operator:x:11:0:operator:/root:/sbin/nologin

นอกจากนี้ หมายเลขบรรทัดที่มีบรรทัดที่ค้นหาจะปรากฏขึ้น

# grep -v bash /etc/passwd | grep -v nologin sync:x:5:0:sync:/sbin:/bin/sync ปิดเครื่อง: x:6:0:shutdown:/sbin:/sbin/shutdown หยุด: x:7:0:halt:/sbin :/sbin/halt news:x:9:13:news:/var/spool/news: mailnull:x:47:47::/var/spool/mqueue:/dev/null xfs:x:43:43: เซิร์ฟเวอร์แบบอักษร X:/etc/X11/fs:/bin/false rpc:x:32:32:Portmapper ผู้ใช้ RPC:/:/bin/false nscd:x:28:28:NSCD Daemon:/:/bin/false ชื่อ:x:25:25:ชื่อ:/var/ชื่อ:/bin/false squid:x:23:23::/var/spool/squid:/dev/null ldap:x:55:55:LDAP ผู้ใช้: /var/lib/ldap:/bin/false apache:x:48:48:Apache:/var/www:/bin/false

ตรวจสอบว่าผู้ใช้รายใดที่ไม่ได้ใช้ bash ยกเว้นบัญชีผู้ใช้ที่ระบุ nologin เป็นเชลล์

# grep -c false /etc/passwd 7

นับจำนวนบัญชีที่มี /bin/false เป็นเชลล์

# grep -i เกม ~/.bash* | ประวัติ grep -v

คำสั่งนี้แสดงบรรทัดจากไฟล์ทั้งหมดในโฮมไดเร็กทอรี ผู้ใช้ปัจจุบันซึ่งชื่อขึ้นต้นด้วย ~/.bash ยกเว้นไฟล์ที่มีชื่อมีประวัติสตริง เพื่อแยกรายการที่ตรงกันที่พบในไฟล์ ~/.bash_history ซึ่งอาจมีบรรทัดเดียวกันที่ด้านบนหรือตัวพิมพ์เล็ก โปรดทราบว่ามีการค้นหาคำว่า "เกม" คุณสามารถทดแทนคำอื่นแทนได้
คำสั่ง grep และนิพจน์ทั่วไป

ต่างจากตัวอย่างก่อนหน้านี้ ตอนนี้เราจะแสดงเฉพาะบรรทัดที่ขึ้นต้นด้วยบรรทัด “root”:

# grep ^root /etc/passwd root:x:0:0:root:/root:/bin/bash

หากเราต้องการดูว่าบัญชีใดที่ไม่ได้ใช้เชลล์เลย เราจะมองหาบรรทัดที่ลงท้ายด้วยอักขระ ///:

# grep:$ /etc/passwd ข่าว:x:9:13:news:/var/spool/news:

หากต้องการตรวจสอบว่าตัวแปร PATH ในไฟล์ ~/.bashrc ของคุณถูกส่งออกหรือไม่ ให้เลือกบรรทัดที่มี "export" ก่อน จากนั้นมองหาบรรทัดที่ขึ้นต้นด้วยบรรทัด "PATH" ในกรณีนี้ MANPATH และอื่นๆ จะไม่แสดงขึ้นมา วิธีที่เป็นไปได้:

# grep ส่งออก ~/.bashrc | grep "PATH" ส่งออก PATH="/bin:/usr/lib/mh:/lib:/usr/bin:/usr/local/bin:/usr/ucb:/usr/dbin:$PATH"

คลาสตัวละคร

นิพจน์ในวงเล็บเหลี่ยมคือรายการอักขระที่อยู่ภายในอักขระ [" และ "]"" ตรงกับอักขระเดี่ยวใดๆ ที่ระบุในรายการนี้ หากอักขระตัวแรกของรายการคือ "^" แสดงว่าตรงกับอักขระใดๆ ที่ไม่อยู่ในรายการ ตัวอย่างเช่น นิพจน์ทั่วไป "" จะจับคู่ตัวเลขหลักเดียวใดๆ

ภายในนิพจน์ในวงเล็บเหลี่ยม คุณสามารถระบุช่วงที่ประกอบด้วยอักขระสองตัวคั่นด้วยยัติภังค์ได้ จากนั้น นิพจน์จะจับคู่ซิงเกิลตันใดๆ ที่ตามกฎการเรียงลำดับ จะอยู่ภายในอักขระสองตัวนี้ รวมถึงอักขระสองตัวนี้ด้วย ซึ่งจะคำนึงถึงการจัดเรียงและชุดอักขระที่ระบุในโลแคล ตัวอย่างเช่น เมื่อภาษาเริ่มต้นคือ C นิพจน์ "" จะเทียบเท่ากับนิพจน์ "" มีหลายสถานที่ซึ่งการเรียงลำดับจะดำเนินการตามลำดับพจนานุกรม และโดยทั่วไปแล้วในสถานที่เหล่านี้ "" จะไม่เทียบเท่ากับ "" ซึ่งอาจเทียบเท่ากับนิพจน์ "" เป็นต้น หากต้องการใช้การตีความนิพจน์วงเล็บแบบดั้งเดิม คุณสามารถใช้โลแคล C ได้โดยตั้งค่าตัวแปรสภาพแวดล้อม LC_ALL เป็น "C"

สุดท้ายนี้ มีคลาสอักขระที่มีชื่อพิเศษ ซึ่งระบุไว้ในนิพจน์ในวงเล็บเหลี่ยม ข้อมูลเพิ่มเติมสำหรับข้อมูลเกี่ยวกับนิพจน์ที่กำหนดไว้ล่วงหน้าเหล่านี้ โปรดดูเอกสารคู่มือ man page หรือคำสั่ง grep

# grep /etc/group sys:x:3:root,bin,adm tty:x:5: mail:x:12:mail,postfix ftp:x:50: ไม่มีใคร:x:99: ฟล็อปปี้ดิสก์:x:19: xfs:x:43: nfsnobody:x:65534: postfix:x:89:

ตัวอย่างจะแสดงทุกบรรทัดที่มีอักขระ "y" หรืออักขระ "f"
อักขระสากล (อักขระเมตา)

ใช้ "." เพื่อให้ตรงกับอักขระตัวเดียว หากคุณต้องการรายการคำศัพท์ภาษาอังกฤษทั้งหมดที่นำมาจากพจนานุกรมที่มีอักขระห้าตัวที่ขึ้นต้นด้วย "c" และลงท้ายด้วย "h" (มีประโยชน์สำหรับการแก้ปริศนาอักษรไขว้):

#เกรป" " /usr/share/dict/words catch clash cloth โค้ชโซฟา ไอพัง ปิ๊ง

หากคุณต้องการแสดงบรรทัดที่มีอักขระจุดเป็นตัวอักษร ให้ระบุตัวเลือก -F ในคำสั่ง grep สัญลักษณ์ "< " и «>" หมายถึง การมีช่องว่างก่อนและหลังตัวอักษรที่ระบุ ซึ่งหมายความว่าคำในไฟล์คำจะต้องเขียนตามนั้น หากคุณต้องการค้นหาคำทั้งหมดในข้อความตามรูปแบบที่กำหนดโดยไม่ต้องคำนึงถึงบรรทัดว่างให้ละเว้นสัญลักษณ์ "< " и «>" หากต้องการค้นหาเฉพาะคำที่แม่นยำยิ่งขึ้น ให้ใช้สวิตช์ -w

ในทำนองเดียวกัน ค้นหาคำที่สามารถมีจำนวนอักขระเท่าใดก็ได้ระหว่าง "c" และ "h" ให้ใช้เครื่องหมายดอกจัน (*) ตัวอย่างด้านล่างเลือกคำทั้งหมดที่ขึ้นต้นด้วย "c" และลงท้ายด้วย "h" จากพจนานุกรมของระบบ:

#เกรป" " /usr/share/dict/words caliph cash catch cheetah --output ละเว้น--

หากคุณต้องการค้นหาเครื่องหมายดอกจันตามตัวอักษรในไฟล์หรือเอาต์พุตสตรีม ให้ใช้ คำพูดเดียว. ขั้นแรกผู้ใช้ในตัวอย่างด้านล่างนี้พยายามค้นหา "เครื่องหมายดอกจัน" ในไฟล์ /etc/profile โดยไม่ต้องใช้เครื่องหมายคำพูด ซึ่งส่งผลให้ไม่พบสิ่งใดเลย เมื่อใช้เครื่องหมายคำพูด ผลลัพธ์ที่ได้คือ:

# grep * /etc/profile # grep "*" /etc/profile สำหรับฉันใน /etc/profile.d/*.sh ; ทำ

เพื่อประมวลผลข้อความในสคริปต์ทุบตีโดยใช้ sed และ awk อย่างสมบูรณ์ คุณเพียงแค่ต้องเข้าใจนิพจน์ทั่วไป การใช้งานเครื่องมือที่มีประโยชน์ที่สุดนี้สามารถพบได้ทุกที่ และแม้ว่านิพจน์ทั่วไปทั้งหมดจะมีโครงสร้างในลักษณะเดียวกันและอิงจากแนวคิดเดียวกัน แต่การทำงานกับนิพจน์เหล่านี้ในสภาพแวดล้อมที่แตกต่างกันก็มีคุณสมบัติบางอย่าง ที่นี่เราจะพูดถึงนิพจน์ทั่วไปที่เหมาะสำหรับใช้ในสคริปต์ บรรทัดคำสั่งลินุกซ์.

เนื้อหานี้มีจุดมุ่งหมายเพื่อเป็นการแนะนำนิพจน์ทั่วไป มีไว้สำหรับผู้ที่อาจไม่รู้เลยว่ามันคืออะไร เรามาเริ่มจากจุดเริ่มต้นกันก่อน

นิพจน์ทั่วไปคืออะไร

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


ในความเห็นของเรา แม้แต่มือใหม่ก็สามารถเข้าใจได้ทันทีว่ามันทำงานอย่างไรและทำไมจึงจำเป็น :) หากคุณยังไม่เข้าใจมากนัก เพียงอ่านต่อแล้วทุกอย่างจะเข้าที่
นิพจน์ทั่วไปเป็นรูปแบบที่โปรแกรมเช่น sed หรือ awk ใช้ในการกรองข้อความ เทมเพลตใช้อักขระ ASCII ปกติที่แสดงถึงตัวเอง และที่เรียกว่าอักขระเมตาที่มีบทบาทพิเศษ เช่น ช่วยให้สามารถอ้างอิงถึงกลุ่มอักขระบางกลุ่มได้

ประเภทของนิพจน์ทั่วไป

การใช้งานนิพจน์ทั่วไปในสภาพแวดล้อมที่แตกต่างกัน เช่น ในภาษาการเขียนโปรแกรมเช่น Java, Perl และ Python และในเครื่องมือ Linux เช่น sed, awk และ grep มีฟีเจอร์บางอย่าง คุณลักษณะเหล่านี้ขึ้นอยู่กับสิ่งที่เรียกว่าเอ็นจิ้นนิพจน์ทั่วไป ซึ่งตีความรูปแบบ
Linux มีเอ็นจิ้นนิพจน์ทั่วไปสองตัว:
  • กลไกที่รองรับมาตรฐาน POSIX Basic Regular Expression (BRE)
  • กลไกที่รองรับมาตรฐาน POSIX Extended Regular Expression (ERE)
ยูทิลิตี้ Linux ส่วนใหญ่เป็นไปตามมาตรฐาน POSIX BRE เป็นอย่างน้อย แต่ยูทิลิตี้บางตัว (รวมถึง sed) เข้าใจเพียงส่วนย่อยของมาตรฐาน BRE เหตุผลประการหนึ่งสำหรับข้อ จำกัด นี้คือความปรารถนาที่จะทำให้ยูทิลิตี้ดังกล่าวเร็วที่สุดในการประมวลผลข้อความ

มาตรฐาน POSIX ERE มักใช้ในภาษาการเขียนโปรแกรม จะช่วยให้คุณสามารถใช้งานได้ จำนวนมากเครื่องมือสำหรับการพัฒนานิพจน์ทั่วไป ตัวอย่างเช่น อาจเป็นลำดับอักขระพิเศษสำหรับรูปแบบที่ใช้บ่อย เช่น การค้นหาคำแต่ละคำหรือชุดตัวเลขในข้อความ Awk รองรับมาตรฐาน ERE

มีหลายวิธีในการพัฒนานิพจน์ทั่วไป ขึ้นอยู่กับทั้งความคิดเห็นของโปรแกรมเมอร์และคุณสมบัติของเอ็นจิ้นที่ถูกสร้างขึ้น การเขียนนิพจน์ทั่วไปที่เป็นสากลซึ่งกลไกใดๆ ก็สามารถเข้าใจได้ไม่ใช่เรื่องง่าย ดังนั้นเราจะมุ่งเน้นไปที่นิพจน์ทั่วไปที่ใช้บ่อยที่สุดและดูคุณลักษณะของการนำไปใช้สำหรับ sed และ awk

นิพจน์ทั่วไป POSIX BRE

บางทีรูปแบบ BRE ที่ง่ายที่สุดอาจเป็นนิพจน์ทั่วไปสำหรับการค้นหาลำดับอักขระในข้อความที่เกิดขึ้นจริง นี่คือลักษณะการค้นหาสตริงใน sed และ awk:

$ echo "นี่คือการทดสอบ" | sed -n "/test/p" $ echo "นี่คือการทดสอบ" | awk "/test/(พิมพ์ $0)"

ค้นหาข้อความตามรูปแบบใน sed


การค้นหาข้อความตามรูปแบบใน awk

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

เมื่อทำงานกับนิพจน์ทั่วไป คุณต้องคำนึงว่านิพจน์เหล่านี้คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่:

$ echo "นี่คือการทดสอบ" | awk "/Test/(พิมพ์ $0)" $ echo "นี่คือการทดสอบ" | awk "/test/(พิมพ์ $0)"

นิพจน์ทั่วไปจะคำนึงถึงขนาดตัวพิมพ์

นิพจน์ทั่วไปแรกไม่พบรายการที่ตรงกัน เนื่องจากคำว่า "ทดสอบ" ซึ่งขึ้นต้นด้วยตัวพิมพ์ใหญ่ไม่ปรากฏในข้อความ ประการที่สองกำหนดค่าให้ค้นหาคำที่เขียนด้วยตัวพิมพ์ใหญ่พบบรรทัดที่เหมาะสมในสตรีม

ในนิพจน์ทั่วไป คุณสามารถใช้ได้ไม่เพียงแต่ตัวอักษรเท่านั้น แต่ยังสามารถใช้ช่องว่างและตัวเลขได้ด้วย:

$ echo "นี่คือการทดสอบ 2 อีกครั้ง" | awk "/ทดสอบ 2/(พิมพ์ $0)"

การค้นหาข้อความที่มีการเว้นวรรคและตัวเลข

ช่องว่างจะถือเป็นอักขระปกติโดยเอ็นจิ้นนิพจน์ทั่วไป

สัญลักษณ์พิเศษ

โดยใช้ ตัวละครต่างๆในนิพจน์ทั่วไป คุณต้องคำนึงถึงคุณลักษณะบางอย่างด้วย ดังนั้นจึงมีอักขระพิเศษหรืออักขระเมตาบางตัว ซึ่งการใช้ในเทมเพลตต้องใช้วิธีพิเศษ พวกเขาอยู่ที่นี่:

.*^${}\+?|()
หากจำเป็นต้องใช้หนึ่งในนั้นในเทมเพลต จะต้องหลีกเลี่ยงโดยใช้เครื่องหมายแบ็กสแลช (แบ็กสแลช) - \

ตัวอย่างเช่น หากคุณต้องการค้นหาเครื่องหมายดอลลาร์ในข้อความ คุณต้องรวมเครื่องหมายนั้นไว้ในเทมเพลต โดยนำหน้าด้วยอักขระหลีก สมมติว่ามีไฟล์ myfile พร้อมข้อความต่อไปนี้:

มีเงิน 10$ ในกระเป๋าของฉัน
เครื่องหมายดอลลาร์สามารถตรวจพบได้โดยใช้รูปแบบนี้:

$awk "/\$/(พิมพ์ $0)" myfile

การใช้อักขระพิเศษในรูปแบบ

นอกจากนี้ แบ็กสแลชยังเป็นอักขระพิเศษ ดังนั้น หากคุณต้องการใช้เป็นรูปแบบ ก็จะต้อง Escape ด้วย ดูเหมือนว่ามีเครื่องหมายทับสองอันต่อกัน:

$ echo "\ เป็นอักขระพิเศษ" | awk "/\\/(พิมพ์ $0)"

หนีแบ็กสแลช

แม้ว่าเครื่องหมายทับจะไม่รวมอยู่ในรายการอักขระพิเศษด้านบน แต่การพยายามใช้ในนิพจน์ทั่วไปที่เขียนสำหรับ sed หรือ awk จะส่งผลให้เกิดข้อผิดพลาด:

$ echo "3/2" | awk "///(พิมพ์ $0)"

การใช้เครื่องหมายทับในรูปแบบไม่ถูกต้อง

หากจำเป็นก็ต้องหลบหนีด้วย:

$ echo "3/2" | awk "/\//(พิมพ์ $0)"

หลบหนีการเฉือนไปข้างหน้า

สัญลักษณ์แองเคอร์

มีอักขระพิเศษสองตัวสำหรับการเชื่อมโยงรูปแบบกับจุดเริ่มต้นหรือจุดสิ้นสุดของสตริงข้อความ อักขระ cap - ^ ช่วยให้คุณสามารถอธิบายลำดับของอักขระที่พบที่จุดเริ่มต้นของบรรทัดข้อความ หากรูปแบบที่คุณกำลังมองหาอยู่ที่อื่นในสตริง นิพจน์ทั่วไปจะไม่ตอบสนองต่อรูปแบบนั้น การใช้สัญลักษณ์นี้มีลักษณะดังนี้:

$ echo "ยินดีต้อนรับสู่เว็บไซต์ likegeeks" | awk "/^likegeeks/(พิมพ์ $0)" $ echo "เว็บไซต์ likegeeks" | awk "/^likegeeks/(พิมพ์ $0)"

ค้นหารูปแบบที่จุดเริ่มต้นของสตริง

อักขระ ^ ได้รับการออกแบบมาเพื่อค้นหารูปแบบที่จุดเริ่มต้นของบรรทัด ในขณะที่คำนึงถึงตัวพิมพ์ของอักขระด้วย มาดูกันว่าสิ่งนี้ส่งผลต่อการประมวลผลไฟล์ข้อความอย่างไร:

$awk "/^this/(พิมพ์ $0)" myfile


การค้นหารูปแบบที่จุดเริ่มต้นของบรรทัดในข้อความจากไฟล์

เมื่อใช้ sed หากคุณวาง cap ไว้ที่ใดที่หนึ่งภายในรูปแบบ มันจะถือว่าเหมือนกับอักขระปกติอื่นๆ:

$ echo "นี่คือการทดสอบ" | sed -n "/s ^/p"

Cap ไม่ได้อยู่ที่จุดเริ่มต้นของรูปแบบใน sed

ใน awk เมื่อใช้เทมเพลตเดียวกัน จะต้องยกเว้นอักขระนี้:

$ echo "นี่คือการทดสอบ" | awk "/s\^/(พิมพ์ $0)"

หน้าปกไม่ได้อยู่ที่จุดเริ่มต้นของเทมเพลตใน awk

เราได้ค้นพบการค้นหาส่วนของข้อความที่อยู่ต้นบรรทัดแล้ว จะทำอย่างไรถ้าคุณต้องการค้นหาบางสิ่งที่อยู่ท้ายบรรทัด?

เครื่องหมายดอลลาร์ - $ ซึ่งเป็นอักขระจุดยึดที่ท้ายบรรทัดจะช่วยเราในเรื่องนี้:

$ echo "นี่คือการทดสอบ" | awk "/test$/(พิมพ์ $0)"

การค้นหาข้อความที่ท้ายบรรทัด

คุณสามารถใช้สัญลักษณ์จุดยึดทั้งสองในเทมเพลตเดียวกันได้ มาประมวลผลไฟล์ myfile ซึ่งมีเนื้อหาแสดงในรูปด้านล่างโดยใช้นิพจน์ทั่วไปต่อไปนี้:

$ awk "/^นี่คือการทดสอบ$/(พิมพ์ $0)" myfile


รูปแบบที่ใช้อักขระพิเศษเพื่อเริ่มต้นและสิ้นสุดบรรทัด

อย่างที่คุณเห็น เทมเพลตตอบสนองเฉพาะบรรทัดที่สอดคล้องกับลำดับอักขระที่กำหนดและตำแหน่งของอักขระเท่านั้น

ต่อไปนี้เป็นวิธีกรองบรรทัดว่างโดยใช้อักขระจุดยึด:

$awk "!/^$/(พิมพ์ $0)" myfile
ในเทมเพลตนี้ ฉันใช้สัญลักษณ์ปฏิเสธ เครื่องหมายอัศเจรีย์ - ! . การใช้รูปแบบนี้ค้นหาบรรทัดที่ไม่มีอะไรเลยระหว่างจุดเริ่มต้นและจุดสิ้นสุดของบรรทัด และต้องขอบคุณ เครื่องหมายอัศเจรีย์เฉพาะบรรทัดที่ไม่ตรงกับรูปแบบนี้เท่านั้นที่จะถูกพิมพ์

สัญลักษณ์จุด

จุดใช้เพื่อจับคู่อักขระเดี่ยวใดๆ ยกเว้นอักขระขึ้นบรรทัดใหม่ ให้เราส่งไฟล์ myfile ไปยังนิพจน์ทั่วไปนี้ ซึ่งมีเนื้อหาระบุไว้ด้านล่าง:

$awk "/.st/(พิมพ์ $0)" myfile


การใช้จุดในนิพจน์ทั่วไป

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

คลาสตัวละคร

จุดจะตรงกับอักขระตัวเดียว แต่ถ้าคุณต้องการจำกัดชุดอักขระที่คุณกำลังมองหาให้ยืดหยุ่นมากขึ้นล่ะ ในสถานการณ์นี้ คุณสามารถใช้คลาสอักขระได้

ด้วยวิธีนี้ คุณสามารถจัดระเบียบการค้นหาตัวละครจากชุดที่กำหนดได้ เพื่ออธิบายคลาสอักขระ จะใช้วงเล็บเหลี่ยม:

$awk "/th/(print $0)" myfile


คำอธิบายของคลาสอักขระในนิพจน์ทั่วไป

ที่นี่เรากำลังมองหาลำดับของอักขระ "th" ที่นำหน้าด้วยอักขระ "o" หรืออักขระ "i"

ชั้นเรียนมีประโยชน์เมื่อค้นหาคำที่สามารถขึ้นต้นด้วยตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็ก:

$ echo "นี่คือการทดสอบ" | awk "/ของเขาคือการทดสอบ/(พิมพ์ $0)" $ echo "นี่คือการทดสอบ" | awk "/เขาคือการทดสอบ/(พิมพ์ $0)"

ค้นหาคำที่อาจขึ้นต้นด้วยตัวพิมพ์เล็กหรือตัวพิมพ์ใหญ่

คลาสอักขระไม่จำกัดเฉพาะตัวอักษร สามารถใช้สัญลักษณ์อื่นๆ ได้ที่นี่ เป็นไปไม่ได้ที่จะพูดล่วงหน้าว่าต้องใช้คลาสสถานการณ์ใด - ทั้งหมดขึ้นอยู่กับปัญหาที่ได้รับการแก้ไข

การปฏิเสธคลาสตัวละคร

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

$ awk "/[^oi]th/(พิมพ์ $0)" myfile


การค้นหาตัวละครที่ไม่ได้อยู่ในชั้นเรียน

ในกรณีนี้ จะพบลำดับของอักขระ "th" ที่นำหน้าด้วยทั้ง "o" และ "i"

ช่วงอักขระ

ในคลาสอักขระ คุณสามารถอธิบายช่วงของอักขระโดยใช้เครื่องหมายขีดกลางได้:

$awk "/st/(พิมพ์ $0)" myfile


คำอธิบายช่วงของตัวละครในคลาสตัวละคร

ใน ในตัวอย่างนี้นิพจน์ทั่วไปตอบสนองต่อลำดับของอักขระ "st" ที่นำหน้าด้วยอักขระใดๆ ที่อยู่ในนั้น ลำดับตัวอักษรระหว่างอักขระ "e" และ "p"

คุณสามารถสร้างช่วงจากตัวเลขได้:

$ echo "123" | awk "//" $ echo "12a" | อ้าว "//"

นิพจน์ทั่วไปเพื่อค้นหาตัวเลขสามตัวใดๆ

คลาสอักขระสามารถมีได้หลายช่วง:

$awk "/st/(พิมพ์ $0)" myfile


คลาสอักขระที่ประกอบด้วยหลายช่วง

นิพจน์ทั่วไปนี้จะค้นหาลำดับทั้งหมดของ "st" ที่นำหน้าด้วยอักขระจาก ช่วง AFและ ม-ซ

คลาสตัวละครพิเศษ

BRE มีคลาสอักขระพิเศษที่คุณสามารถใช้เพื่อเขียนนิพจน์ทั่วไป:
  • [[:alpha:]] - จับคู่อักขระตัวอักษรใดๆ ที่เขียนด้วยตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็ก
  • [[:alnum:]] - จับคู่อักขระตัวอักษรและตัวเลข ได้แก่ อักขระในช่วง 0-9 , A-Z , a-z
  • [[:blank:]] - จับคู่ช่องว่างและอักขระแท็บ
  • [[:digit:]] - อักขระหลักใดก็ได้ตั้งแต่ 0 ถึง 9
  • [[:upper:]] - อักขระตัวพิมพ์ใหญ่ - A-Z
  • [[:lower:]] - อักขระตัวพิมพ์เล็ก - a-z
  • [[:print:]] - จับคู่อักขระที่สามารถพิมพ์ได้
  • [[:punct:]] - จับคู่เครื่องหมายวรรคตอน
  • [[:ช่องว่าง:]] - อักขระช่องว่างโดยเฉพาะอย่างยิ่ง - ช่องว่าง แท็บ อักขระ NL, FF, VT, CR
คุณสามารถใช้คลาสพิเศษในเทมเพลตดังนี้:

$ echo "abc" | awk "/[[:alpha:]]/(พิมพ์ $0)" $ echo "abc" | awk `/[[:digit:]]/(พิมพ์ $0)" $ echo "abc123" | awk `/[[:digit:]]/(พิมพ์ $0)"


คลาสอักขระพิเศษในนิพจน์ทั่วไป

สัญลักษณ์รูปดาว

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

$ echo "ทดสอบ" | awk "/tes*t/(พิมพ์ $0)" $ echo "tessst" | awk "/tes*t/(พิมพ์ $0)"


การใช้อักขระ * ในนิพจน์ทั่วไป

โดยทั่วไปไวด์การ์ดนี้ใช้สำหรับคำที่สะกดผิดตลอดเวลาหรือคำที่อยู่ภายใต้ ตัวแปรที่แตกต่างกันการสะกดที่ถูกต้อง:

$ echo "ฉันชอบสีเขียว" | awk "/colou*r/(พิมพ์ $0)" $ echo "ฉันชอบสีเขียว" | awk "/colou*r/(พิมพ์ $0)"

การค้นหาคำที่มีการสะกดต่างกัน

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

คุณสมบัติที่มีประโยชน์อีกประการหนึ่งที่มาจากเครื่องหมายดอกจันคือการรวมเข้ากับจุด การรวมกันนี้ทำให้นิพจน์ทั่วไปสามารถตอบสนองต่ออักขระจำนวนเท่าใดก็ได้:

$ awk "/this.*test/(พิมพ์ $0)" myfile


เทมเพลตที่ตอบสนองต่ออักขระจำนวนเท่าใดก็ได้

ในกรณีนี้ ไม่ว่าจะมีอักขระกี่ตัวและอยู่ระหว่างคำว่า "นี้" และ "ทดสอบ"

เครื่องหมายดอกจันยังสามารถใช้กับคลาสอักขระได้:

$ echo "st" | awk "/s*t/(พิมพ์ $0)" $ echo "sat" | awk "/s*t/(พิมพ์ $0)" $ echo "set" | awk "/s*t/(พิมพ์ $0)"


การใช้เครื่องหมายดอกจันกับคลาสอักขระ

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

นิพจน์ทั่วไป POSIX ERE

เทมเพลต POSIX ERE ที่ยูทิลิตี้ Linux บางตัวรองรับอาจมีอักขระเพิ่มเติม ดังที่ได้กล่าวไปแล้ว awk รองรับมาตรฐานนี้ แต่ sed ไม่รองรับ

ที่นี่เราจะดูสัญลักษณ์ที่ใช้บ่อยที่สุดในรูปแบบ ERE ซึ่งจะเป็นประโยชน์กับคุณเมื่อสร้างนิพจน์ทั่วไปของคุณเอง

▍เครื่องหมายคำถาม

เครื่องหมายคำถามบ่งชี้ว่าอักขระนำหน้าอาจปรากฏขึ้นเพียงครั้งเดียวหรือไม่ปรากฏเลยในข้อความ อักขระนี้เป็นหนึ่งในอักขระเมตาของการทำซ้ำ นี่คือตัวอย่างบางส่วน:

$ echo "tet" | awk "/tes?t/(พิมพ์ $0)" $ echo "test" | awk "/tes?t/(พิมพ์ $0)" $ echo "tesst" | awk "/tes?t/(พิมพ์ $0)"


เครื่องหมายคำถามในนิพจน์ทั่วไป

อย่างที่คุณเห็น ในกรณีที่สาม ตัวอักษร "s" ปรากฏขึ้นสองครั้ง ดังนั้นนิพจน์ทั่วไปจึงไม่ตอบสนองต่อคำว่า "testst"

เครื่องหมายคำถามยังสามารถใช้กับคลาสอักขระได้:

$ echo "tst" | awk "/t?st/(พิมพ์ $0)" $ echo "test" | awk "/t?st/(พิมพ์ $0)" $ echo "tast" | awk "/t?st/(พิมพ์ $0)" $ echo "taest" | awk "/t?st/(พิมพ์ $0)" $ echo "teest" | awk "/t?st/(พิมพ์ $0)"


เครื่องหมายคำถามและคลาสตัวละคร

หากไม่มีอักขระจากคลาสในบรรทัด หรืออักขระตัวใดตัวหนึ่งปรากฏขึ้นเพียงครั้งเดียว นิพจน์ทั่วไปจะทำงาน แต่ทันทีที่อักขระสองตัวปรากฏในคำ ระบบจะไม่พบรายการที่ตรงกันสำหรับรูปแบบในข้อความอีกต่อไป

▍เครื่องหมายบวก

อักขระบวกในรูปแบบบ่งชี้ว่านิพจน์ทั่วไปจะตรงกับสิ่งที่ต้องการหากอักขระที่อยู่หน้าปรากฏอย่างน้อยหนึ่งครั้งในข้อความ อย่างไรก็ตาม โครงสร้างนี้จะไม่ตอบสนองต่อการไม่มีสัญลักษณ์:

$ echo "ทดสอบ" | awk "/te+st/(พิมพ์ $0)" $ echo "teest" | awk "/te+st/(พิมพ์ $0)" $ echo "tst" | awk "/te+st/(พิมพ์ $0)"


สัญลักษณ์บวกในนิพจน์ทั่วไป

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

$ echo "tst" | awk "/t+st/(พิมพ์ $0)" $ echo "test" | awk "/t+st/(พิมพ์ $0)" $ echo "teast" | awk "/t+st/(พิมพ์ $0)" $ echo "teeast" | awk "/t+st/(พิมพ์ $0)"


เครื่องหมายบวกและคลาสตัวละคร

ในกรณีนี้ หากบรรทัดมีอักขระใดๆ จากคลาส ข้อความจะถือว่าตรงกับรูปแบบ

▍เหล็กจัดฟันแบบหยิก

เครื่องหมายปีกกาซึ่งสามารถใช้ในรูปแบบ ERE นั้นคล้ายคลึงกับสัญลักษณ์ที่กล่าวถึงข้างต้น แต่ช่วยให้คุณระบุจำนวนการเกิดสัญลักษณ์ที่อยู่ข้างหน้าได้อย่างแม่นยำยิ่งขึ้น คุณสามารถระบุข้อจำกัดได้สองรูปแบบ:
  • n - ตัวเลขที่ระบุจำนวนการค้นหาที่แน่นอน
  • n, m เป็นตัวเลขสองตัวที่ตีความได้ดังนี้: “อย่างน้อย n ครั้ง แต่ไม่เกิน m”
นี่คือตัวอย่างของตัวเลือกแรก:

$ echo "tst" | awk "/te(1)st/(พิมพ์ $0)" $ echo "test" | awk "/te(1)st/(พิมพ์ $0)"

วงเล็บปีกกาในรูปแบบ ค้นหาจำนวนครั้งที่แน่นอน

ใน awk เวอร์ชันเก่า คุณต้องใช้ตัวเลือกบรรทัดคำสั่ง --re-interval เพื่อทำให้โปรแกรมรู้จักช่วงเวลาในนิพจน์ทั่วไป แต่ในเวอร์ชันใหม่กว่านี้ไม่จำเป็น

$ echo "tst" | awk "/te(1,2)st/(พิมพ์ $0)" $ echo "test" | awk "/te(1,2)st/(พิมพ์ $0)" $ echo "teest" | awk "/te(1,2)st/(พิมพ์ $0)" $ echo "teeest" | awk "/te(1,2)st/(พิมพ์ $0)"


ระยะห่างที่ระบุในวงเล็บปีกกา

ในตัวอย่างนี้ อักขระ “e” ต้องปรากฏ 1 หรือ 2 ครั้งในบรรทัด จากนั้นนิพจน์ทั่วไปจะตอบสนองต่อข้อความ

วงเล็บปีกกายังสามารถใช้กับคลาสอักขระได้ หลักการที่คุณรู้อยู่แล้วใช้ได้ที่นี่:

$ echo "tst" | awk "/t(1,2)st/(พิมพ์ $0)" $ echo "test" | awk "/t(1,2)st/(พิมพ์ $0)" $ echo "teest" | awk "/t(1,2)st/(พิมพ์ $0)" $ echo "teeast" | awk "/t(1,2)st/(พิมพ์ $0)"


วงเล็บปีกกาและคลาสตัวละคร

เทมเพลตจะตอบสนองต่อข้อความหากมีอักขระ “a” หรืออักขระ “e” หนึ่งหรือสองครั้ง

▍สัญลักษณ์ "หรือ" แบบลอจิคัล

สัญลักษณ์ | - แถบแนวตั้งหมายถึง "หรือ" แบบตรรกะในนิพจน์ทั่วไป เมื่อประมวลผลนิพจน์ทั่วไปที่มีส่วนต่างๆ คั่นด้วยเครื่องหมายดังกล่าว กลไกจะพิจารณาข้อความที่วิเคราะห์อย่างเหมาะสมหากตรงกับส่วนใดๆ นี่คือตัวอย่าง:

$ echo "นี่คือการทดสอบ" | awk "/test|exam/(พิมพ์ $0)" $ echo "นี่คือการสอบ" | awk "/test|exam/(พิมพ์ $0)" $ echo "นี่คืออย่างอื่น" | awk "/test|exam/(พิมพ์ $0)"


ตรรกะ "หรือ" ในนิพจน์ทั่วไป

ในตัวอย่างนี้ นิพจน์ทั่วไปได้รับการกำหนดค่าให้ค้นหาข้อความสำหรับคำว่า "test" หรือ "exam" โปรดทราบว่าระหว่างส่วนของเทมเพลตและสัญลักษณ์ที่แยกพวกมัน | ไม่ควรมีช่องว่าง

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

$ echo "ชอบ" | awk "/Like(Geeks)?/(พิมพ์ $0)" $ echo "LikeGeeks" | awk "/ชอบ(Geeks)?/(พิมพ์ $0)"


การจัดกลุ่มส่วนของนิพจน์ทั่วไป

ในตัวอย่างเหล่านี้ คำว่า "Geeks" จะอยู่ในวงเล็บ ตามด้วยเครื่องหมายคำถาม โปรดจำไว้ว่าเครื่องหมายคำถามหมายถึง "0 หรือ 1 การซ้ำซ้อน" ดังนั้นนิพจน์ทั่วไปจะตอบสนองต่อทั้งสตริง "Like" และสตริง "LikeGeeks"

ตัวอย่างการปฏิบัติ

ตอนนี้เราได้ครอบคลุมพื้นฐานของนิพจน์ทั่วไปแล้ว ก็ถึงเวลาทำสิ่งที่มีประโยชน์กับนิพจน์เหล่านี้

▍การนับจำนวนไฟล์

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

$ echo $PATH | sed "s/:/ /g"
คำสั่งแทนที่สนับสนุนนิพจน์ทั่วไปเป็นรูปแบบสำหรับการค้นหาข้อความ ในกรณีนี้ทุกอย่างง่ายมากเรากำลังมองหาสัญลักษณ์โคลอน แต่ไม่มีใครรบกวนเราใช้อย่างอื่นที่นี่ - ทุกอย่างขึ้นอยู่กับงานเฉพาะ
ตอนนี้คุณต้องผ่านรายการผลลัพธ์แบบวนซ้ำและดำเนินการที่จำเป็นเพื่อนับจำนวนไฟล์ โครงร่างทั่วไปของสคริปต์จะเป็นดังนี้:

Mypath=$(echo $PATH | sed "s/:/ /g") สำหรับไดเร็กทอรีใน $mypath เสร็จแล้ว
ตอนนี้เรามาเขียนข้อความทั้งหมดของสคริปต์โดยใช้คำสั่ง ls เพื่อรับข้อมูลเกี่ยวกับจำนวนไฟล์ในแต่ละไดเร็กทอรี:

#!/bin/bash mypath=$(echo $PATH | sed "s/:/ /g") count=0 สำหรับไดเร็กทอรีใน $mypath do check=$(ls $directory) สำหรับรายการใน $check do count=$ [ $count + 1 ] เสร็จแล้ว echo "$directory - $count" count=0 เสร็จแล้ว
เมื่อเรียกใช้สคริปต์ อาจกลายเป็นว่าไม่มีบางไดเร็กทอรีจาก PATH อย่างไรก็ตาม สิ่งนี้จะไม่ป้องกันไม่ให้นับไฟล์ในไดเร็กทอรีที่มีอยู่


การนับไฟล์

ค่าหลักของตัวอย่างนี้คือการใช้แนวทางเดียวกัน คุณสามารถแก้ปัญหาที่ซับซ้อนมากขึ้นได้ อันไหนขึ้นอยู่กับความต้องการของคุณ

▍การยืนยันที่อยู่อีเมล

มีเว็บไซต์ที่มีคอลเลกชันนิพจน์ทั่วไปมากมายที่ให้คุณตรวจสอบที่อยู่ได้ อีเมล, หมายเลขโทรศัพท์และอื่นๆ อย่างไรก็ตาม การนำของบางอย่างสำเร็จรูปมาเป็นอีกเรื่องหนึ่ง และเป็นอีกเรื่องหนึ่งในการสร้างบางสิ่งด้วยตัวเอง เรามาเขียนนิพจน์ทั่วไปเพื่อตรวจสอบที่อยู่อีเมลกัน เริ่มต้นด้วยการวิเคราะห์แหล่งข้อมูล ตัวอย่างเช่น นี่คือที่อยู่ที่แน่นอน:

[ป้องกันอีเมล]
ชื่อผู้ใช้ ชื่อผู้ใช้ สามารถประกอบด้วยตัวอักษรและตัวเลขและอักขระอื่นๆ กล่าวคือ นี่คือจุด ขีดกลาง ขีดล่าง และเครื่องหมายบวก Username ตามด้วยเครื่องหมาย @

ด้วยความรู้นี้ มาเริ่มประกอบนิพจน์ทั่วไปจากด้านซ้ายซึ่งใช้ในการตรวจสอบชื่อผู้ใช้กันดีกว่า นี่คือสิ่งที่เราได้รับ:

^(+)@
นิพจน์ทั่วไปนี้สามารถอ่านได้ดังนี้: “บรรทัดต้องเริ่มต้นด้วยอักขระอย่างน้อยหนึ่งตัวจากที่อยู่ในกลุ่มที่ระบุในวงเล็บเหลี่ยม ตามด้วยเครื่องหมาย @”

ตอนนี้ - คิวชื่อโฮสต์ - ชื่อโฮสต์ ชื่อผู้ใช้จะใช้กฎเดียวกันนี้ ดังนั้นเทมเพลตของชื่อผู้ใช้จะมีลักษณะดังนี้:

(+)
ชื่อโดเมนระดับบนสุดอยู่ภายใต้บังคับ กฎพิเศษ. สามารถมีได้เฉพาะอักขระตัวอักษร ซึ่งต้องมีอย่างน้อยสองตัว (เช่น โดเมนดังกล่าวมักจะมีรหัสประเทศ) และไม่เกินห้าตัว ทั้งหมดนี้หมายความว่าเทมเพลตสำหรับตรวจสอบส่วนสุดท้ายของที่อยู่จะเป็นดังนี้:

\.({2,5})$
คุณสามารถอ่านได้ดังนี้: “ขั้นแรกต้องมีจุด จากนั้นจึงตามด้วยตัวอักษร 2 ถึง 5 ตัว และหลังจากนั้นบรรทัดจะสิ้นสุด”

เมื่อเตรียมเทมเพลตสำหรับแต่ละส่วนของนิพจน์ทั่วไปแล้ว เรามารวมกัน:

^(+)@(+)\.({2,5})$
ตอนนี้สิ่งที่เหลืออยู่คือการทดสอบว่าเกิดอะไรขึ้น:

$ เอคโค่ " [ป้องกันอีเมล]" | awk "/^(+)@(+)\.((2,5))$/(พิมพ์ $0)" $ echo " [ป้องกันอีเมล]" | awk "/^(+)@(+)\.((2,5))$/(พิมพ์ $0)"


การตรวจสอบที่อยู่อีเมลโดยใช้นิพจน์ทั่วไป

ความจริงที่ว่าข้อความที่ส่งไปยัง awk ปรากฏบนหน้าจอหมายความว่าระบบจำได้ว่าเป็นที่อยู่อีเมล

ผลลัพธ์

หากนิพจน์ทั่วไปในการตรวจสอบที่อยู่อีเมลที่คุณพบในตอนต้นของบทความดูเหมือนจะไม่สามารถเข้าใจได้อย่างสมบูรณ์เราหวังว่าตอนนี้มันจะดูไม่เหมือนชุดอักขระที่ไร้ความหมายอีกต่อไป ถ้าเป็นเช่นนั้นจริงๆ ก็หมายความว่า วัสดุนี้บรรลุวัตถุประสงค์ของมัน ในความเป็นจริง นิพจน์ทั่วไปเป็นหัวข้อที่คุณสามารถศึกษาได้ตลอดชีวิต แต่แม้แต่สิ่งเล็กๆ น้อยๆ ที่เรากล่าวถึงก็สามารถช่วยให้คุณเขียนสคริปต์ที่ประมวลผลข้อความได้ค่อนข้างสูง

ในชุดเนื้อหานี้เรามักจะแสดงให้เห็นอย่างมาก ตัวอย่างง่ายๆสคริปต์ทุบตีที่ประกอบด้วยหลายบรรทัดอย่างแท้จริง ครั้งต่อไปเราจะดูสิ่งที่ใหญ่กว่านี้

เรียนผู้อ่าน! คุณใช้นิพจน์ทั่วไปเมื่อประมวลผลข้อความในสคริปต์บรรทัดคำสั่งหรือไม่

หนึ่งในทีมที่มีประโยชน์และเต็มไปด้วยฟีเจอร์มากที่สุดใน เทอร์มินัลลินุกซ์– คำสั่ง “grep” Grep เป็นตัวย่อที่ย่อมาจาก "การพิมพ์นิพจน์ทั่วไปทั่วโลก" (นั่นคือ "ค้นหาทุกที่เพื่อหาสตริงที่ตรงกับนิพจน์ทั่วไปแล้วพิมพ์ออกมา") ซึ่งหมายความว่า grep สามารถใช้เพื่อดูว่าอินพุตตรงกับรูปแบบที่ระบุหรือไม่

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

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

พื้นฐานของการใช้งาน

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

ตามตัวอย่าง คุณสามารถใช้ grep เพื่อค้นหาบรรทัดที่มีคำว่า "GNU" ใน GNU General Public License เวอร์ชัน 3 บนระบบ Ubuntu

cd /usr/share/common-licenses.cd
grep "GNU" GPL-3
ใบอนุญาตสาธารณะทั่วไปของ GNU





13. ใช้กับ GNU Affero General Public License
ภายใต้เวอร์ชัน 3 ของ GNU Affero General Public License เป็นหนึ่งเดียว
...
...

อาร์กิวเมนต์แรก "GNU" คือรูปแบบที่จะค้นหา และอาร์กิวเมนต์ที่สอง "GPL-3" คือไฟล์อินพุตที่จะพบ

เป็นผลให้ทุกบรรทัดที่มีรูปแบบข้อความจะถูกส่งออก ในบางส่วน การแจกแจงลินุกซ์รูปแบบที่คุณกำลังมองหาจะถูกเน้นในบรรทัดเอาต์พุต

ตัวเลือกทั่วไป

ตามค่าเริ่มต้น คำสั่ง grep เพียงค้นหารูปแบบที่ระบุอย่างเคร่งครัดในไฟล์อินพุต และพิมพ์บรรทัดที่พบ อย่างไรก็ตาม พฤติกรรมของ grep สามารถเปลี่ยนแปลงได้โดยการเพิ่มแฟล็กเพิ่มเติม

หากคุณต้องการละเว้นตัวพิมพ์เล็กของพารามิเตอร์การค้นหา และค้นหารูปแบบทั้งตัวพิมพ์ใหญ่และตัวพิมพ์เล็กของรูปแบบ คุณสามารถใช้ยูทิลิตี "-i" หรือ "--ignore-case"

ตามตัวอย่าง คุณสามารถใช้ grep เพื่อค้นหาคำว่า "license" ในไฟล์เดียวกันที่เขียนด้วยตัวพิมพ์ใหญ่ ตัวพิมพ์เล็ก หรือตัวพิมพ์ผสม

grep -i "ใบอนุญาต" GPL-3
ใบอนุญาตสาธารณะทั่วไปของ GNU
ของเอกสารใบอนุญาตนี้แต่ไม่อนุญาตให้เปลี่ยนแปลง
GNU General Public License เป็นใบอนุญาตลิขสิทธิ์ฟรีสำหรับ
ลิขสิทธิ์ซอฟต์แวร์ส่วนใหญ่และผลงานเชิงปฏิบัติอื่นๆ ได้รับการออกแบบ
ใบอนุญาตสาธารณะทั่วไปของ GNU มีวัตถุประสงค์เพื่อรับประกันอิสรภาพของคุณในการ
GNU General Public License สำหรับซอฟต์แวร์ส่วนใหญ่ของเรา มันใช้กับด้วย


"ใบอนุญาตนี้" หมายถึงเวอร์ชัน 3 ของใบอนุญาตสาธารณะทั่วไปของ GNU
"โปรแกรม" หมายถึงงานที่มีลิขสิทธิ์ใด ๆ ที่ได้รับอนุญาตภายใต้สิ่งนี้
...
...

อย่างที่คุณเห็น ผลลัพธ์ประกอบด้วย "LICENSE", "license" และ "License" หากมีอินสแตนซ์ของ "LiCeNsE" ในไฟล์ ไฟล์นั้นก็จะถูกส่งออกเช่นกัน
หากคุณต้องการค้นหาบรรทัดทั้งหมดที่ไม่มีรูปแบบที่ระบุ คุณสามารถใช้แฟล็ก "-v" หรือ "--invert-match"

ตามตัวอย่าง คุณสามารถใช้คำสั่งต่อไปนี้เพื่อค้นหาใบอนุญาต BSD สำหรับทุกบรรทัดที่ไม่มีคำว่า "the":

grep -v "ที่" BSD
สงวนลิขสิทธิ์.
การแจกจ่ายซ้ำและการใช้งานในรูปแบบซอร์สและไบนารี่ โดยมีหรือไม่มีก็ได้
เป็นไปตาม:
อาจใช้เพื่อรับรองหรือส่งเสริมผลิตภัณฑ์ที่ได้จากซอฟต์แวร์นี้
โดยไม่ได้รับอนุญาตเป็นลายลักษณ์อักษรล่วงหน้าเป็นการเฉพาะ
ซอฟต์แวร์นี้จัดทำโดยผู้สำเร็จราชการแทนพระองค์และผู้มีส่วนร่วม ``ตามสภาพที่เป็นอยู่" ​​และ
การรับประกันโดยชัดแจ้งหรือโดยนัย รวมถึงแต่ไม่จำกัดเพียง
...
...

อย่างที่คุณเห็น สองบรรทัดสุดท้ายถูกส่งออกโดยไม่มีคำว่า "the" เนื่องจากไม่ได้ใช้คำสั่ง "ignore case"

การทราบหมายเลขบรรทัดที่พบการแข่งขันจะเป็นประโยชน์เสมอ สามารถพบได้โดยใช้แฟล็ก "-n" หรือ "--line-number"

หากคุณใช้แฟล็กนี้ในตัวอย่างก่อนหน้านี้ ผลลัพธ์ต่อไปนี้จะปรากฏขึ้น:

grep -vn "ที่" BSD
2: สงวนลิขสิทธิ์
3:
4: การแจกจ่ายและการใช้งานในรูปแบบซอร์สและไบนารี่ โดยมีหรือไม่มีก็ได้
6:พบแล้ว:
13: อาจใช้เพื่อรับรองหรือส่งเสริมผลิตภัณฑ์ที่ได้รับจากซอฟต์แวร์นี้
14: โดยไม่ได้รับอนุญาตเป็นลายลักษณ์อักษรล่วงหน้าโดยเฉพาะ
15:
16: ซอฟต์แวร์นี้จัดทำโดยผู้สำเร็จราชการแทนพระองค์และผู้มีส่วนร่วม ``ตามสภาพที่เป็นอยู่" และ
17: การรับประกันโดยชัดแจ้งหรือโดยนัย รวมถึงแต่ไม่จำกัดเพียง
...
...

ตอนนี้คุณสามารถอ้างอิงถึงหมายเลขบรรทัดได้เมื่อคุณต้องการเปลี่ยนแปลงแต่ละบรรทัดที่ไม่มี "the"

นิพจน์ทั่วไป

ตามที่กล่าวไว้ในบทนำ grep ย่อมาจาก "การพิมพ์นิพจน์ทั่วไปทั่วโลก" นิพจน์ทั่วไปคือสตริงข้อความที่อธิบายรูปแบบการค้นหาเฉพาะ

แอปพลิเคชันและภาษาการเขียนโปรแกรมที่แตกต่างกันใช้นิพจน์ทั่วไปแตกต่างกันเล็กน้อย บทช่วยสอนนี้ครอบคลุมเพียงส่วนย่อยเล็กน้อยของวิธีการอธิบายรูปแบบสำหรับ Grep

การจับคู่ตัวอักษร

ในตัวอย่างข้างต้นของการค้นหาคำว่า "GNU" และ "the" มีการค้นหานิพจน์ทั่วไปที่เรียบง่ายซึ่งตรงกับสตริงอักขระ "GNU" และ "the" ทุกประการ

เป็นการถูกต้องมากกว่าที่จะคิดว่าสิ่งเหล่านี้เป็นการจับคู่สตริงของอักขระมากกว่าการจับคู่คำ เมื่อคุณคุ้นเคยกับรูปแบบที่ซับซ้อนมากขึ้น ความแตกต่างนี้จะมีความสำคัญมากขึ้น

รูปแบบที่ตรงกับอักขระที่กำหนดทุกประการเรียกว่ารูปแบบ "ตัวอักษร" เนื่องจากตรงกับรูปแบบตัวอักษรต่อตัวอักษร อักขระต่ออักขระ

อักขระตัวอักษรและตัวเลขทั้งหมด (และอักขระอื่นๆ บางตัว) จะตรงกันตามตัวอักษร เว้นแต่จะได้รับการแก้ไขโดยกลไกการแสดงออกอื่นๆ

การแข่งขันสมอ

จุดยึดเป็นอักขระพิเศษที่ระบุตำแหน่งในสตริงของการจับคู่ที่ต้องการ

ตัวอย่างเช่น คุณสามารถระบุได้ว่าการค้นหาต้องการเฉพาะบรรทัดที่มีคำว่า "GNU" ในตอนต้นเท่านั้น ในการดำเนินการนี้ คุณจะต้องใช้จุดยึด “^” หน้าสตริงตัวอักษร

ตัวอย่างนี้พิมพ์เฉพาะบรรทัดที่มีคำว่า "GNU" อยู่ที่จุดเริ่มต้นเท่านั้น

grep "^GNU" GPL-3
GNU General Public License สำหรับซอฟต์แวร์ส่วนใหญ่ของเรา มันใช้กับด้วย
GNU General Public License คุณสามารถเลือกเวอร์ชันใดก็ได้ที่เคยเผยแพร่

ในทำนองเดียวกัน สามารถใช้จุดยึด "$" หลังสตริงตัวอักษรเพื่อระบุว่าการจับคู่จะใช้ได้ก็ต่อเมื่อสตริงอักขระที่กำลังค้นหาอยู่ที่ส่วนท้ายของสตริงข้อความ

นิพจน์ทั่วไปต่อไปนี้จะพิมพ์เฉพาะบรรทัดที่มี "และ" ต่อท้าย:

grep "และ$" GPL-3
ไม่มีการรับประกันสำหรับซอฟต์แวร์ฟรีนี้ สำหรับทั้งผู้ใช้" และ
ข้อกำหนดและเงื่อนไขที่ชัดเจนสำหรับการคัดลอก แจกจ่าย และ


ทางเลือกอื่นได้รับอนุญาตเป็นครั้งคราวเท่านั้นและไม่ใช่เชิงพาณิชย์และ
เครือข่ายอาจถูกปฏิเสธเมื่อมีการปรับเปลี่ยนอย่างมีนัยสำคัญและ
ส่งผลเสียต่อการทำงานของเครือข่ายหรือฝ่าฝืนกฎและ
เป็นการชั่วคราว เว้นแต่และจนกว่าเจ้าของลิขสิทธิ์จะระบุไว้โดยชัดแจ้งและ
ได้รับใบอนุญาตจากผู้อนุญาตเดิมให้ดำเนินการแก้ไขและ
ผลิต ใช้ ขาย เสนอขาย นำเข้า และดำเนินการ ดัดแปลง และ

จับคู่ตัวละครใดก็ได้

จุด (.) ใช้ในนิพจน์ทั่วไปเพื่อระบุว่าอักขระใดๆ สามารถปรากฏในตำแหน่งที่ระบุได้

ตัวอย่างเช่น หากคุณต้องการค้นหารายการที่ตรงกันที่มีอักขระสองตัวแล้วตามด้วยลำดับ "cept" คุณจะใช้รูปแบบต่อไปนี้:

grep "..cept" GPL-3
การใช้งานซึ่งเป็นจุดที่ยอมรับไม่ได้มากที่สุด ดังนั้นเราจึง
การละเมิดภายใต้กฎหมายลิขสิทธิ์ที่บังคับใช้ ยกเว้นการดำเนินการบน
แจ้งผู้ใช้งานว่าไม่มีการรับประกันผลงาน (ยกเว้นตัว

รูปแบบของใบอนุญาตเป็นลายลักษณ์อักษรแยกต่างหาก หรือระบุเป็นข้อยกเว้น
คุณไม่สามารถเผยแพร่หรือแก้ไขงานที่ครอบคลุมได้ยกเว้นโดยชัดแจ้ง
9. ไม่จำเป็นต้องมีการยอมรับสำหรับการมีสำเนา
...
...

อย่างที่คุณเห็น ผลลัพธ์ประกอบด้วยคำว่า "ยอมรับ" และ "ยกเว้น" รวมถึงรูปแบบต่างๆ ของคำเหล่านี้ รูปแบบจะตรงกับลำดับ “z2cept” หากอยู่ในข้อความ

นิพจน์ในวงเล็บ

ด้วยการวางกลุ่มอักขระภายในวงเล็บเหลี่ยม ("") คุณสามารถระบุได้ว่าอักขระใดๆ ในวงเล็บสามารถปรากฏที่ตำแหน่งนั้นได้

ซึ่งหมายความว่า หากคุณต้องการค้นหาสตริงที่มี "too" หรือ "two" คุณสามารถระบุรูปแบบเหล่านี้โดยย่อโดยใช้รูปแบบต่อไปนี้:

grep "ถึง" GPL-3
โปรแกรมของคุณด้วย

นักพัฒนาซอฟต์แวร์ที่ใช้ GNU GPL ปกป้องสิทธิ์ของคุณด้วยสองขั้นตอน:
เครือข่ายคอมพิวเตอร์ที่ไม่มีการถ่ายโอนสำเนาจะไม่ถูกถ่ายทอด

แหล่งที่มาที่สอดคล้องกันจากเซิร์ฟเวอร์เครือข่ายโดยไม่มีค่าใช้จ่าย
...
...

อย่างที่คุณเห็น พบทั้งสองรูปแบบในไฟล์

การใส่อักขระในวงเล็บยังมีคุณลักษณะที่เป็นประโยชน์หลายประการอีกด้วย คุณสามารถระบุได้ว่าทุกอย่างยกเว้นอักขระในวงเล็บตรงกับรูปแบบโดยการเริ่มรายการอักขระในวงเล็บด้วยอักขระ “^”

ตัวอย่างนี้ใช้รูปแบบ ".ode" ซึ่งต้องไม่ตรงกับลำดับ "code"

grep "[^c]ode" GPL-3
1. ซอร์สโค้ด
แบบจำลองเพื่อให้ใครก็ตามที่ครอบครองรหัสวัตถุอย่างใดอย่างหนึ่ง (1)
โหมดการใช้งานผลิตภัณฑ์ที่สำคัญเพียงอย่างเดียว
สังเกตเช่นนี้เมื่อเริ่มต้นในโหมดโต้ตอบ:

เป็นที่น่าสังเกตว่าบรรทัดที่สองมีคำว่า "code" นี่ไม่ใช่ข้อผิดพลาด regex หรือ grep

แต่บรรทัดนี้ถูกพิมพ์ออกมาเนื่องจากมี "โหมด" ลำดับการจับคู่รูปแบบที่พบในคำว่า "รุ่น" นั่นคือสตริงถูกพิมพ์เพราะมันตรงกับรูปแบบ

อีกอันหนึ่ง คุณสมบัติที่มีประโยชน์วงเล็บ - ความสามารถในการระบุช่วงของอักขระแทนที่จะป้อนอักขระแต่ละตัวแยกกัน

ซึ่งหมายความว่า หากคุณต้องการค้นหาทุกบรรทัดที่ขึ้นต้นด้วยตัวพิมพ์ใหญ่ คุณสามารถใช้รูปแบบต่อไปนี้:

grep "^" GPL-3
GNU General Public License สำหรับซอฟต์แวร์ส่วนใหญ่ของเรา มันใช้กับด้วย

ใบอนุญาต. ผู้รับอนุญาตแต่ละรายจะมีการระบุชื่อเป็น "คุณ" “ใบอนุญาต” และ


System Libraries หรือเครื่องมืออเนกประสงค์หรือทั่วไปมีให้ฟรี
แหล่งที่มา.

...
...

เนื่องจากปัญหาการจัดเรียงโดยธรรมชาติบางประการ เพื่อให้ผลลัพธ์ที่แม่นยำยิ่งขึ้น ควรใช้คลาสอักขระ POSIX แทนช่วงอักขระที่ใช้ในตัวอย่างด้านบน
มีคลาสอักขระหลายคลาสที่ไม่ครอบคลุมในคู่มือนี้ ตัวอย่างเช่น หากต้องการดำเนินการตามขั้นตอนเดียวกับในตัวอย่างด้านบน คุณสามารถใช้คลาสอักขระ "[:upper:]" ในวงเล็บได้

grep "^[[:upper:]]" GPL-3
GNU General Public License สำหรับซอฟต์แวร์ส่วนใหญ่ของเรา มันใช้กับด้วย
รัฐไม่ควรอนุญาตให้สิทธิบัตรจำกัดการพัฒนาและการใช้
ใบอนุญาต. ผู้รับอนุญาตแต่ละรายจะมีการระบุชื่อเป็น "คุณ" “ใบอนุญาต” และ
ส่วนประกอบ และ (ข) ทำหน้าที่เพียงเพื่อให้ใช้งานกับสิ่งนั้นได้
ส่วนประกอบหลักหรือเพื่อใช้อินเทอร์เฟซมาตรฐานซึ่ง
System Libraries หรือเครื่องมืออเนกประสงค์หรือทั่วไปมีให้ฟรี
แหล่งที่มา.
ผลิตภัณฑ์ของผู้ใช้จะถูกโอนไปยังผู้รับตลอดไปหรือเพื่อ
...
...

ทำซ้ำรูปแบบ (0 ครั้งขึ้นไป)

เมตาอักขระที่ใช้กันมากที่สุดตัวหนึ่งคือสัญลักษณ์ "*" ซึ่งหมายถึง "ทำซ้ำอักขระก่อนหน้าหรือนิพจน์ 0 หรือมากกว่านั้น"

ตัวอย่างเช่น หากคุณต้องการค้นหาทุกบรรทัดที่มีวงเล็บเปิดหรือปิดที่มีเฉพาะตัวอักษรและช่องว่างระหว่างวงเล็บ คุณสามารถใช้นิพจน์ต่อไปนี้:

grep "(*)" GPL-3

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

วิธีหลีกเลี่ยงอักขระเมตา

บางครั้งคุณอาจต้องมองหาจุดตามตัวอักษรหรือวงเล็บเปิดตามตัวอักษร เนื่องจากอักขระเหล่านี้มีความหมายเฉพาะในนิพจน์ทั่วไป คุณจึงต้อง "escape" อักขระเหล่านี้โดยบอก grep ว่าไม่จำเป็นต้องใช้ความหมายพิเศษในกรณีนี้

อักขระเหล่านี้สามารถหลีกได้โดยใช้เครื่องหมายแบ็กสแลช (\) หน้าอักขระ ซึ่งโดยปกติจะมีความหมายพิเศษ

ตัวอย่างเช่น หากคุณต้องการค้นหาสตริงที่ขึ้นต้นด้วยตัวพิมพ์ใหญ่และลงท้ายด้วยจุด คุณสามารถใช้นิพจน์ด้านล่างได้ เครื่องหมายแบ็กสแลชก่อนจุดสุดท้ายจะบอกคำสั่งให้ "escape" เพื่อให้จุดสุดท้ายแทนจุดตามตัวอักษรและไม่มีความหมาย "ใดๆ":

grep "^.*\.$" GPL-3
แหล่งที่มา.
อนุญาตโดยการยกเว้นจากเงื่อนไขหนึ่งข้อขึ้นไป
ใบอนุญาตจะต้องงดเว้นการถ่ายทอดโปรแกรมโดยสิ้นเชิง
การบริการ ซ่อมแซม หรือแก้ไขที่จำเป็นทั้งหมด
ความเสียหายดังกล่าว
เพิ่มข้อมูลเกี่ยวกับวิธีการติดต่อคุณทางอิเล็กทรอนิกส์และทางไปรษณีย์

นิพจน์ทั่วไปขั้นสูง

คำสั่ง Grep ยังสามารถใช้กับภาษานิพจน์ทั่วไปแบบขยายได้โดยใช้แฟล็ก -E หรือโดยการเรียกคำสั่ง egrep แทน grep

คำสั่งเหล่านี้เปิดความสามารถของ "นิพจน์ทั่วไปแบบขยาย" นิพจน์ทั่วไปแบบขยายประกอบด้วยอักขระเมตาพื้นฐานทั้งหมด ตลอดจนอักขระเมตาเพิ่มเติมเพื่อแสดงการจับคู่ที่ซับซ้อนมากขึ้น

การจัดกลุ่ม

หนึ่งในคุณลักษณะที่ง่ายที่สุดและมีประโยชน์มากที่สุดที่ขยายนิพจน์ทั่วไปคือความสามารถในการจัดกลุ่มนิพจน์และใช้เป็นหน่วยเดียว

วงเล็บใช้เพื่อจัดกลุ่มนิพจน์ หากคุณต้องการใช้วงเล็บนอกนิพจน์ทั่วไปแบบขยาย คุณสามารถ "หลีก" ได้โดยใช้แบ็กสแลช

grep "\(การจัดกลุ่ม\)" file.txt
grep -E "(การจัดกลุ่ม)" file.txt
egrep "(การจัดกลุ่ม)" file.txt

สำนวนข้างต้นเทียบเท่ากัน

การสลับกัน

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

สัญลักษณ์แถบแนวตั้ง “|” ใช้เพื่อระบุการสลับ การสลับมักใช้ในการจัดกลุ่มเพื่อระบุว่าตัวเลือกใดตัวเลือกหนึ่งจากสองตัวขึ้นไปควรได้รับการพิจารณาว่าตรงกัน

ในตัวอย่างนี้ คุณต้องค้นหา “GPL” หรือ “General Public License”:

grep -E "(GPL|ใบอนุญาตสาธารณะทั่วไป)" GPL-3
GNU General Public License เป็นใบอนุญาตลิขสิทธิ์ฟรีสำหรับ
ใบอนุญาตสาธารณะทั่วไปของ GNU มีวัตถุประสงค์เพื่อรับประกันอิสรภาพของคุณในการ
GNU General Public License สำหรับซอฟต์แวร์ส่วนใหญ่ของเรา มันใช้กับด้วย
ราคา. ใบอนุญาตสาธารณะทั่วไปของเราได้รับการออกแบบมาเพื่อให้แน่ใจว่าคุณ
นักพัฒนาซอฟต์แวร์ที่ใช้ GNU GPL ปกป้องสิทธิ์ของคุณด้วยสองขั้นตอน:
สำหรับการปกป้องนักพัฒนา "และผู้แต่ง" GPL อธิบายไว้อย่างชัดเจน
ผู้เขียน" เห็นแก่ GPL กำหนดให้เวอร์ชันที่แก้ไขต้องถูกทำเครื่องหมายเป็น
ได้ออกแบบ GPL เวอร์ชันนี้เพื่อห้ามการปฏิบัติดังกล่าว
...
...

การสลับสามารถใช้เพื่อเลือกระหว่างสองตัวเลือกขึ้นไป ในการดำเนินการนี้ คุณจะต้องป้อนตัวเลือกที่เหลือลงในกลุ่มการเลือก โดยแยกแต่ละรายการโดยใช้สัญลักษณ์แถบแนวตั้ง “|”

ปริมาณ

ในนิพจน์ทั่วไปแบบขยาย มีอักขระเมตาที่ระบุว่าอักขระซ้ำบ่อยแค่ไหน เหมือนกับอักขระเมตา "*" ที่ระบุว่าอักขระก่อนหน้าหรือสตริงของอักขระตรงกับ 0 ครั้งขึ้นไป

หากต้องการจับคู่อักขระ 0 ครั้งขึ้นไป คุณสามารถใช้อักขระ "?" ได้ มันจะทำให้อักขระก่อนหน้าหรือชุดอักขระเป็นทางเลือก

ในตัวอย่างนี้ โดยการแทรกลำดับ "สำเนา" ลงในกลุ่มที่ไม่บังคับ ระบบจะแสดง "ลิขสิทธิ์" และ "ขวา":

grep -E "(คัดลอก)?ขวา" GPL-3
ลิขสิทธิ์ (C) 2007 Free Software Foundation, Inc.
เพื่อปกป้องสิทธิ์ของคุณ เราจำเป็นต้องป้องกันไม่ให้ผู้อื่นปฏิเสธคุณ
สิทธิเหล่านี้หรือขอให้คุณสละสิทธิ์ ดังนั้นคุณจึงมี
รู้สิทธิของตน
นักพัฒนาซอฟต์แวร์ที่ใช้ GNU GPL ปกป้องสิทธิ์ของคุณด้วยสองขั้นตอน:
(1) ยืนยันลิขสิทธิ์ซอฟต์แวร์ และ (2) เสนอใบอนุญาตนี้แก่คุณ
"ลิขสิทธิ์" ยังหมายถึงกฎหมายลิขสิทธิ์ที่มีผลใช้กับกฎหมายประเภทอื่นๆ ด้วย
...
...

อักขระ "+" ตรงกับนิพจน์ 1 ครั้งขึ้นไป ทำงานเกือบจะเหมือนกับสัญลักษณ์ "*" แต่เมื่อใช้ "+" นิพจน์จะต้องตรงกันอย่างน้อย 1 ครั้ง

นิพจน์ต่อไปนี้ตรงกับสตริง "free" บวกอักขระ 1 ตัวขึ้นไปที่ไม่ใช่ช่องว่าง:

grep -E "free[^[:space:]]+" GPL-3
GNU General Public License เป็นใบอนุญาตลิขสิทธิ์ฟรีสำหรับ
เพื่อเอาเสรีภาพของคุณในการแบ่งปันและเปลี่ยนแปลงผลงาน ตรงกันข้าม,
ใบอนุญาตสาธารณะทั่วไปของ GNU มีวัตถุประสงค์เพื่อรับประกันอิสรภาพของคุณในการ
เมื่อเราพูดถึงซอฟต์แวร์เสรี เรากำลังหมายถึงเสรีภาพ ไม่ใช่
มีอิสระในการแจกจ่ายสำเนาซอฟต์แวร์ฟรี (และคิดค่าบริการ

เสรีภาพที่คุณได้รับ คุณต้องแน่ใจว่าพวกเขาได้รับเช่นกัน
ปกป้องผู้ใช้" เสรีภาพในการเปลี่ยนแปลงซอฟต์แวร์อย่างเป็นระบบ
ของ GPL ตามความจำเป็นเพื่อปกป้องเสรีภาพของผู้ใช้
ไม่สามารถใช้สิทธิบัตรเพื่อทำให้โปรแกรมไม่ฟรี

จำนวนการแข่งขันซ้ำ

หากคุณต้องการระบุจำนวนครั้งที่ตรงกันซ้ำ คุณสามารถใช้วงเล็บปีกกา (“( )”) สัญลักษณ์เหล่านี้ใช้เพื่อระบุจำนวน ช่วง และขีดจำกัดบนและล่างของจำนวนรายการที่ตรงกันของนิพจน์

หากคุณต้องการค้นหาบรรทัดทั้งหมดที่มีสระสามตัวรวมกัน คุณสามารถใช้นิพจน์ต่อไปนี้:

grep -E "(3)" GPL-3
เปลี่ยนแปลงไปเพื่อไม่ให้เกิดปัญหาขึ้นอย่างผิดพลาด
ผู้เขียนเวอร์ชันก่อนหน้า
รับมันในสื่อใด ๆ โดยมีเงื่อนไขว่าคุณต้องเห็นได้ชัดเจนและ
ให้ตามวรรคก่อนบวกสิทธิครอบครองด้วย
งานที่ครอบคลุมเพื่อสนองภาระผูกพันของคุณภายใต้สิ่งนี้ไปพร้อม ๆ กัน
หากคุณต้องการค้นหาคำทั้งหมดที่ประกอบด้วยอักขระ 16-20 ตัว ให้ใช้นิพจน์ต่อไปนี้:
grep -E "[[:อัลฟา:]](16,20)" GPL-3
ความรับผิดชอบบางประการหากคุณแจกจ่ายสำเนาของซอฟต์แวร์หรือหาก
คุณแก้ไขมัน: ความรับผิดชอบในการเคารพเสรีภาพของผู้อื่น
c) ห้ามการบิดเบือนความจริงเกี่ยวกับที่มาของเนื้อหานั้น หรือ

ข้อสรุป

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

นิพจน์ทั่วไปมีความหลากหลายมากขึ้นและสามารถใช้ได้ในโปรแกรมยอดนิยมมากมาย ตัวอย่างเช่นมากมาย โปรแกรมแก้ไขข้อความใช้นิพจน์ทั่วไปเพื่อค้นหาและแทนที่ข้อความ

นอกจากนี้ ภาษาการเขียนโปรแกรมขั้นสูงยังใช้นิพจน์ทั่วไปเพื่อดำเนินการตามขั้นตอนกับข้อมูลเฉพาะ การรู้วิธีทำงานกับนิพจน์ทั่วไปจะมีประโยชน์เมื่อแก้ไขปัญหาทั่วไปเกี่ยวกับคอมพิวเตอร์

แท็ก: ,

สวัสดีตอนบ่ายแขก!

ในบทความวันนี้ ฉันต้องการพูดถึงหัวข้อใหญ่เช่น นิพจน์ทั่วไป. ฉันคิดว่าทุกคนรู้ดีว่าหัวข้อของ regexes (ซึ่งเรียกว่านิพจน์ทั่วไปในคำสแลง) นั้นกว้างใหญ่ในขอบเขตของโพสต์เดียว ดังนั้น ฉันจะพยายามรวบรวมความคิดของฉันสั้น ๆ แต่ชัดเจนที่สุดเท่าที่จะทำได้และถ่ายทอดให้คุณฟังใน

ผมขอเริ่มด้วยการบอกว่านิพจน์ทั่วไปมีหลายประเภท:

1. นิพจน์ปกติแบบดั้งเดิม(พวกเขายังเป็นพื้นฐาน พื้นฐาน และ นิพจน์ทั่วไปพื้นฐาน(เบรอี))

  • ไวยากรณ์ของนิพจน์เหล่านี้ถูกกำหนดให้ล้าสมัย แต่ก็ยังแพร่หลายและใช้งานโดยยูทิลิตี้ UNIX จำนวนมาก
  • นิพจน์ทั่วไปพื้นฐานประกอบด้วยอักขระเมตาต่อไปนี้ (เพิ่มเติมเกี่ยวกับความหมายด้านล่าง):
    • \( \) - เวอร์ชันเริ่มต้นสำหรับ ( ) (แบบขยาย)
    • \(\) - เวอร์ชันเริ่มต้นสำหรับ () (แบบขยาย)
    • \n, ที่ไหน n- หมายเลขตั้งแต่ 1 ถึง 9
  • คุณสมบัติของการใช้อักขระเมตาเหล่านี้:
    • เครื่องหมายดอกจันต้องตามหลังนิพจน์ที่สอดคล้องกับอักขระตัวเดียว ตัวอย่าง: *.
    • การแสดงออก \( ปิดกั้น\)* ควรถือว่าไม่ถูกต้อง ในบางกรณีจะจับคู่สตริงที่ซ้ำกันเป็นศูนย์หรือมากกว่า ปิดกั้น. ในบางอันมันสอดคล้องกับสตริง ปิดกั้น* .
    • ภายในคลาสอักขระ ความหมายอักขระพิเศษจะถูกละเว้นเป็นส่วนใหญ่ กรณีพิเศษ:
    • หากต้องการเพิ่มอักขระ ^ ให้กับชุด จะต้องไม่วางไว้ก่อน
    • หากต้องการเพิ่มอักขระ - ให้กับชุด จะต้องวางไว้ก่อนหรือหลัง ตัวอย่างเช่น:
      • เทมเพลตชื่อ DNS ซึ่งอาจประกอบด้วยตัวอักษร ตัวเลข ลบ และจุด: [-0-9a-zA-Z.] ;
      • อักขระใดๆ ยกเว้นเครื่องหมายลบและตัวเลข: [^-0-9]
    • หากต้องการเพิ่มอักขระ [ หรือ ] ให้กับชุด จะต้องวางไว้ตรงนั้นก่อน ตัวอย่างเช่น:
      • ตรงกัน ], [, a หรือ b

2. นิพจน์ทั่วไปขั้นสูง(พวกเขาคือ ขยายนิพจน์ทั่วไป(เอเร่))

  • ไวยากรณ์ของนิพจน์เหล่านี้คล้ายกับไวยากรณ์ของนิพจน์หลัก ยกเว้น:
    • ลบการใช้แบ็กสแลชสำหรับอักขระเมตา ( ) และ () ออก
    • แบ็กสแลชก่อนที่อักขระเมตาจะแทนที่ความหมายพิเศษ
    • ถูกปฏิเสธในทางทฤษฎี ไม่สม่ำเสมอออกแบบ\ n .
    • เพิ่มอักขระเมตา + , ? , | .

3. นิพจน์ทั่วไปเข้ากันได้กับ Perl(พวกเขาคือ นิพจน์ทั่วไปที่เข้ากันได้กับ Perl(พีซีอาร์อี))

  • มีไวยากรณ์ที่สมบูรณ์กว่าและในเวลาเดียวกันสามารถคาดเดาได้มากกว่าแม้แต่ POSIX ERE ดังนั้นจึงมักถูกใช้โดยแอปพลิเคชัน

นิพจน์ทั่วไป ประกอบด้วยแม่แบบหรือมากกว่า ตั้งค่าเทมเพลตค้นหา. เทมเพลตประกอบด้วยจาก กฎการค้นหาซึ่งประกอบด้วย ตัวอักษรและ อักขระเมตา.

กฎการค้นหาถูกกำหนดโดยสิ่งต่อไปนี้ การดำเนินงาน:

การแจงนับ |

ท่อ (|)แยกตัวเลือกที่ถูกต้อง ใคร ๆ ก็บอกว่า - ตรรกะหรือ ตัวอย่างเช่น "gray|grey" จะตรงกัน สีเทาหรือ สีเทา.

กลุ่มหรือสหภาพ()

วงเล็บกลมใช้เพื่อกำหนดขอบเขตและลำดับความสำคัญของตัวดำเนินการ ตัวอย่างเช่น "gray|grey" และ "gr(a|e)y" เป็นรูปแบบที่แตกต่างกัน แต่ทั้งสองรูปแบบอธิบายถึงชุดที่ประกอบด้วย สีเทาและ สีเทา.

ปริมาณ()? * +

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

การแสดงออกทั่วไป การซ้ำซ้อนอาจเป็นได้ จาก m ถึง n รวมอยู่ด้วย.

การแสดงออกทั่วไป m หรือมากกว่าการทำซ้ำ.

การแสดงออกทั่วไป ไม่เกิน n ซ้ำ.

เรียบการทำซ้ำ.

เครื่องหมายคำถามวิธี 0 หรือ 1ครั้งเช่นเดียวกับ {0,1} . ตัวอย่างเช่น "colou?r" ตรงกับ และ สี, และ สี.

ดาววิธี 0, 1 หรือตัวเลขใดๆครั้งหนึ่ง ( {0,} ). ตัวอย่างเช่น การจับคู่ "go*gle" ตกลง, Google, Googleและอื่น ๆ.

บวกวิธี อย่างน้อย 1ครั้งหนึ่ง ( {1,} ). ตัวอย่างเช่น การจับคู่ "go+gle" Google, Googleฯลฯ (แต่ไม่ใช่. ตกลง).

ไวยากรณ์ที่แน่นอนของนิพจน์ทั่วไปเหล่านี้ขึ้นอยู่กับการใช้งาน (นั่นคือใน นิพจน์ทั่วไปพื้นฐานสัญลักษณ์ ( และ )- หนีด้วยแบ็กสแลช)

Metaตัวละครกล่าวง่ายๆ ก็คือ สัญลักษณ์ที่ไม่สอดคล้องกับความหมายที่แท้จริง นั่นก็คือ สัญลักษณ์ (จุด) ไม่ใช่จุด แต่เป็นอักขระตัวใดตัวหนึ่ง ฯลฯ โปรดทำความคุ้นเคยกับ meta character และความหมาย:

. สอดคล้องกัน ตามลำพังสัญลักษณ์ใดๆ
[บางสิ่งบางอย่าง] เป็นไปตามข้อกำหนด โสดใดๆอักขระจากที่อยู่ในวงเล็บ ในกรณีนี้: อักขระ “-” จะถูกตีความตามตัวอักษรเฉพาะในกรณีที่อยู่หลังเครื่องหมายเปิดหรือก่อนวงเล็บปิด: หรือ [-abc] มิฉะนั้นจะระบุช่วงอักขระ ตัวอย่างเช่น จับคู่ "a", "b" หรือ "c" สอดคล้องกับอักษรตัวพิมพ์เล็กของอักษรละติน ชื่อเหล่านี้สามารถนำมารวมกันได้: จับคู่ a, b, c, q, r, s, t, u, v, w, x, y, z เพื่อให้ตรงกับอักขระ "[" หรือ "]" ก็เพียงพอแล้วที่ วงเล็บปิดเป็นอักขระตัวแรกหลังอักขระเปิด: จับคู่ "]", "[", "a" หรือ "b" หากค่าในวงเล็บเหลี่ยมนำหน้าด้วยอักขระ ^ ค่าของนิพจน์จะตรงกัน อักขระตัวเดียวจากบรรดาเหล่านั้น ซึ่งไม่อยู่ในวงเล็บ. ตัวอย่างเช่น [^abc] จะจับคู่อักขระอื่นๆ ที่ไม่ใช่ "a", "b" หรือ "c" [^a-z] จับคู่อักขระใดๆ ยกเว้นอักขระตัวพิมพ์เล็กในตัวอักษรละติน
^ จับคู่จุดเริ่มต้นของข้อความ (หรือจุดเริ่มต้นของบรรทัดใดๆ หากโหมดเป็นแบบทีละบรรทัด)
$ จับคู่ส่วนท้ายของข้อความ (หรือส่วนท้ายของบรรทัดใดๆ หากโหมดเป็นแบบทีละบรรทัด)
\(\) หรือ () ประกาศ "การแสดงออกย่อยที่ถูกทำเครื่องหมาย" (การแสดงออกที่จัดกลุ่ม) ที่สามารถนำมาใช้ในภายหลัง (ดูองค์ประกอบต่อไปนี้: \ n). "การแสดงออกย่อยที่ทำเครื่องหมายไว้" ก็เป็น "บล็อก" เช่นกัน ไม่เหมือนกับตัวดำเนินการอื่นๆ ตัวดำเนินการนี้ (ในรูปแบบไวยากรณ์ดั้งเดิม) ต้องใช้เครื่องหมายแบ็กสแลช ส่วนในรูปแบบขยายและ Perl ไม่จำเป็นต้องใช้อักขระ \
\n ที่ไหน n- นี่คือตัวเลขตั้งแต่ 1 ถึง 9; สอดคล้องกัน nนิพจน์ย่อยที่ทำเครื่องหมายไว้ (เช่น (abcd)\0 นั่นคืออักขระ abcd ถูกทำเครื่องหมายด้วยศูนย์) การออกแบบนี้เป็นไปในทางทฤษฎี ไม่สม่ำเสมอไม่ได้รับการยอมรับในไวยากรณ์นิพจน์ทั่วไปแบบขยาย
*
  • ดาวหลังจากนิพจน์ที่ตรงกับอักขระตัวเดียว ให้จับคู่ ศูนย์หรือ มากกว่า สำเนานิพจน์นี้ (ก่อนหน้า) ตัวอย่างเช่น "*" จะจับคู่สตริงว่าง "x", "y", "zx", "zyx" ฯลฯ
  • \n*, ที่ไหน nเป็นตัวเลขตั้งแต่ 1 ถึง 9 ซึ่งจับคู่ศูนย์หรือมากกว่านั้นเพื่อให้ตรงกัน nการแสดงออกย่อยที่ทำเครื่องหมายไว้ ตัวอย่างเช่น "\(a.\)c\1*" จะจับคู่ "abcab" และ "abcaba" แต่ไม่ใช่ "abcac"

นิพจน์ที่อยู่ใน "\(" และ "\)" ตามด้วย "*" ถือว่าผิดกฎหมาย ในบางกรณี จะจับคู่สตริงที่อยู่ในวงเล็บเป็นศูนย์หรือมากกว่านั้น ในกรณีอื่นๆ จะจับคู่นิพจน์ที่อยู่ในวงเล็บโดยใช้อักขระ "*"

\{x,\} ตรงกับอันสุดท้าย ( ที่กำลังจะมาถึง) บล็อกเกิดขึ้นอย่างน้อย xและไม่มีอีกแล้ว ครั้งหนึ่ง. ตัวอย่างเช่น "a\(3,5\)" ตรงกับ "aaa", "aaaa" หรือ "aaaa" ไม่เหมือนกับตัวดำเนินการอื่นๆ ตัวดำเนินการนี้ (ในรูปแบบไวยากรณ์ดั้งเดิม) ต้องใช้เครื่องหมายแบ็กสแลช
.* การกำหนดอักขระจำนวนเท่าใดก็ได้ระหว่างสองส่วนของนิพจน์ทั่วไป

MetaCharacters ช่วยให้เราใช้การจับคู่ต่างๆ แต่เราจะแทน meta character ให้เป็นอักขระปกติได้อย่างไร ซึ่งก็คือสัญลักษณ์ [ (วงเล็บเหลี่ยม) ที่มีความหมายว่าวงเล็บเหลี่ยม? แค่:

  • ต้องมาก่อน ( โล่) metaอักขระ (. * + \ ? ( )) แบ็กสแลช ตัวอย่างเช่น \. หรือ \[

เพื่อให้คำจำกัดความของชุดอักขระบางชุดง่ายขึ้น จึงได้รวมเข้ากับสิ่งที่เรียกว่า คลาสและหมวดหมู่ของตัวละคร. POSIX ได้กำหนดมาตรฐานการประกาศคลาสและหมวดหมู่อักขระบางประเภท ดังแสดงในตารางต่อไปนี้:

คลาส POSIX ในทำนองเดียวกัน การกำหนด
[:บน:] อักขระตัวพิมพ์ใหญ่
[:ต่ำกว่า:] อักขระตัวพิมพ์เล็ก
[:อัลฟ่า:] อักขระตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก
[:อัลบั้ม:] ตัวเลข อักขระตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก
[:หลัก:] ตัวเลข
[:xdigit:] เลขฐานสิบหก
[: ตรงเวลา:] [.,!?:…] เครื่องหมายวรรคตอน
[:ว่างเปล่า:] [\ที] พื้นที่และแท็บ
[:ช่องว่าง:] [\t\n\r\f\v] ข้ามอักขระ
[:ควบคุม:] อักขระควบคุม
[:กราฟ:] [^\t\n\r\f\v] สัญลักษณ์ประทับตรา
[:พิมพ์:] [^\t\n\r\f\v] สัญลักษณ์ประทับตราและสัญลักษณ์ข้าม

ใน regex มีสิ่งเช่น:

ความโลภ regex

ฉันจะพยายามอธิบายให้ชัดเจนที่สุด สมมติว่าเราต้องการค้นหาทุกสิ่ง แท็ก HTMLในข้อความบางส่วน เมื่อแก้ไขปัญหาแล้ว เราต้องการค้นหาค่าที่อยู่ระหว่างนั้น< и >พร้อมด้วยวงเล็บเหลี่ยมเดียวกันนี้ แต่เรารู้ว่าแท็กมีความยาวต่างกันและในตัวมันเองก็มีแท็กอย่างน้อย 50 แท็ก การแสดงแท็กทั้งหมดโดยใส่สัญลักษณ์เมตาเป็นงานที่ใช้เวลานานเกินไป แต่เรารู้ว่าเรามีนิพจน์* (เครื่องหมายดอกจัน) ซึ่งระบุลักษณะของอักขระใดๆ ในบรรทัด โดยใช้ ได้รับการแสดงออกเราจะพยายามค้นหาในข้อความ (

ดังนั้น, วิธีการสร้าง ระดับการโจมตี 10/50 บนคอนโทรลเลอร์ LSI MegaRAID (เกี่ยวข้องกับ: Intel SRCU42x, Intel SRCS16 ด้วย):

) ค่าทั้งหมดระหว่าง< и >. เป็นผลให้ทั้งบรรทัดจะตรงกับนิพจน์นี้ ทำไมเพราะ regex นั้น GREEDY และพยายามจับจำนวนอักขระทั้งหมดระหว่างนั้น< и >ตามลำดับทั้งบรรทัดเริ่มต้น < พี>ดังนั้น...และสิ้นสุด ...> จะเป็นไปตามกฎข้อนี้!

ฉันหวังว่าตัวอย่างนี้จะทำให้ชัดเจนว่าความโลภคืออะไร เพื่อกำจัดความโลภนี้ คุณสามารถปฏิบัติตามเส้นทางต่อไปนี้:

  • คำนึงถึงสัญลักษณ์ ไม่ตรงตามรูปแบบที่ต้องการ (เช่น<[^>]*> สำหรับกรณีข้างต้น)
  • กำจัดความโลภโดยการเพิ่มคำจำกัดความของปริมาณว่าไม่โลภ:
    • *? - "ไม่โลภ" ("ขี้เกียจ") เทียบเท่า *
    • +? - “ไม่โลภ” (“ขี้เกียจ”) เทียบเท่า +
    • (น)? - “ไม่โลภ” (“ขี้เกียจ”) เทียบเท่า (n,)
    • .*? - “ไม่โลภ” (“ขี้เกียจ”) เทียบเท่า*

ฉันต้องการเพิ่มทั้งหมดข้างต้น ไวยากรณ์นิพจน์ทั่วไปแบบขยาย:

นิพจน์ทั่วไปใน POSIX นั้นคล้ายคลึงกับไวยากรณ์ Unix แบบดั้งเดิม แต่มีการเพิ่มอักขระเมตาบางตัว:

บวกบ่งชี้ว่า ก่อนหน้าสัญลักษณ์หรือ กลุ่มอาจทำซ้ำได้ หนึ่งครั้งหรือมากกว่านั้น. ต่างจากเครื่องหมายดอกจัน ต้องมีการแสดงซ้ำอย่างน้อยหนึ่งครั้ง

เครื่องหมายคำถามทำ ก่อนหน้าสัญลักษณ์หรือกลุ่มก็ได้ กล่าวอีกนัยหนึ่งคือในบรรทัดที่สอดคล้องกัน อาจจะขาดหรืออยู่ก็ได้เรียบ หนึ่งครั้งหนึ่ง.

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

การใช้แบ็กสแลชก็ถูกยกเลิกเช่นกัน: \(…\) กลายเป็น (…) และ \(…\) กลายเป็น (…)

เพื่อสรุปโพสต์นี้ ฉันจะยกตัวอย่างการใช้ regex:

$ cat text1 1 แอปเปิ้ล 2 ลูกแพร์ 3 กล้วย $ grep p text1 1 แอปเปิ้ล 2 ลูกแพร์ $ grep "pp*" text1 1 แอปเปิ้ล 2 ลูกแพร์ $ cat text1 | grep "l\|n" 1 แอปเปิ้ล 3 กล้วย $ echo -e "ค้นหา\n* ที่นี่" | grep "\*" * ที่นี่ $ grep "pl\?.*r" text1 # p บนบรรทัดที่มี r 2 pear $ grep "a.." text1 # บรรทัดที่ตามด้วยอักขระอย่างน้อย 2 ตัว 1 apple 3 Banana $ grep "" text1 # ค้นหาบรรทัดที่มี 3 หรือ p 1 apple 2 pear 3 Banana $ echo -e "ค้นหา\n* ที่นี่\nที่ไหนสักแห่ง" | grep "[.*]" * ที่นี่ที่ไหนสักแห่ง..name]$ echo -e "123\n456\n789\n0" | grep "" 123,456,789 $ sed -e "/\(a.*a\)\|\(p.*p\)/s/a/A/g" text1 # แทนที่ a ด้วย A ในทุกบรรทัดโดยที่หลังจากมา a หรือหลัง p มา p 1 Apple 2 pear 3 bAnAnA *\./ LAST WORD./g" First. A LAST WORD. This is a LAST WORD.

ขอแสดงความนับถือ McSim!

grep ย่อมาจาก 'เครื่องพิมพ์นิพจน์ทั่วไปทั่วโลก' grep ตัดบรรทัดที่คุณต้องการ ไฟล์ข้อความซึ่งมีข้อความที่ผู้ใช้ระบุ

grep สามารถใช้ได้สองวิธี - เพียงอย่างเดียวหรือใช้ร่วมกับสตรีม

grep มีฟังก์ชันการทำงานที่กว้างขวางมาก เนื่องจากมีตัวเลือกมากมายที่มันรองรับ เช่น: การค้นหาโดยใช้รูปแบบสตริงหรือรูปแบบนิพจน์ทั่วไป RegExp หรือนิพจน์ทั่วไปที่ใช้ Perl เป็นต้น

เนื่องจากมันแตกต่าง ฟังก์ชั่นเครื่องมือ grep มีตัวเลือกมากมายรวมถึง egrep (ขยาย GREP), fgrep (แก้ไข GREP), pgrep (กระบวนการ GREP), rgrep (GREP แบบเรียกซ้ำ)ฯลฯ แต่ตัวเลือกเหล่านี้มีความแตกต่างเล็กน้อยจาก grep ดั้งเดิม

ตัวเลือก grep

$ grep -V grep (GNU grep) 2.10 ลิขสิทธิ์ (C) 2011 Free Software Foundation, Inc. ใบอนุญาต GPLv3+

มีการแก้ไขยูทิลิตี้ grep: egrep (พร้อมการประมวลผลนิพจน์ทั่วไปแบบขยาย), fgrep (ซึ่งถือว่า $*^|()\ สัญลักษณ์เป็นตัวอักษร เช่น ตัวอักษร), rgrep (พร้อมเปิดใช้งานการค้นหาแบบเรียกซ้ำ)

    egrep เหมือนกับ grep -E

    fgrep เหมือนกับ grep -F

    rgrep เหมือนกับ grep -r

    grep [-b] [-c] [-i] [-l] [-n] [-s] [-v] จำกัด_regex_BRE [ไฟล์...]

คำสั่ง grep จับคู่บรรทัดในไฟล์ต้นฉบับกับรูปแบบที่ระบุโดยlimited_regex หากไม่มีการระบุไฟล์ ระบบจะใช้อินพุตมาตรฐาน โดยทั่วไป แต่ละสตริงที่จับคู่สำเร็จจะถูกคัดลอกไปยังเอาต์พุตมาตรฐาน หากมีไฟล์ต้นฉบับหลายไฟล์ ชื่อไฟล์จะถูกกำหนดไว้หน้าบรรทัดที่พบ grep ใช้อัลกอริธึมที่มีขนาดกะทัดรัดและไม่ได้กำหนดไว้ นิพจน์ทั่วไปแบบจำกัด (นิพจน์ที่มีสตริงอักขระที่มีความหมาย และใช้ชุดอักขระตัวอักษรและตัวเลขและอักขระพิเศษที่จำกัด) จะถูกมองว่าเป็นเทมเพลต มีความหมายเหมือนกับสำนวนปกติใน ed

หากต้องการหลีกเลี่ยงอักขระ $, *, , ^, |, () และ \ จากการตีความเชลล์ วิธีที่ง่ายที่สุดในการใส่ constrained_regex ในเครื่องหมายคำพูดเดี่ยว

ตัวเลือก:

B นำหน้าแต่ละบรรทัดด้วยหมายเลขบล็อกที่พบ สิ่งนี้มีประโยชน์เมื่อค้นหาบล็อกตามบริบท (บล็อกจะมีหมายเลขเริ่มต้นจาก 0) -c พิมพ์เฉพาะจำนวนบรรทัดที่มีรูปแบบ -h ป้องกันชื่อไฟล์ที่มีบรรทัดที่ตรงกันไม่ให้พิมพ์ก่อนบรรทัดนั้น ใช้เมื่อค้นหาไฟล์หลายไฟล์ -i ละเว้นกรณีเมื่อทำการเปรียบเทียบ -l พิมพ์เฉพาะชื่อของไฟล์ที่มีสตริงที่ตรงกัน หนึ่งรายการต่อบรรทัด หากพบรูปแบบในไฟล์หลายบรรทัด ชื่อไฟล์จะไม่ซ้ำกัน -n พิมพ์หมายเลขในไฟล์ก่อนแต่ละบรรทัด (บรรทัดจะมีหมายเลขเริ่มต้นจาก 1) -s ระงับข้อความเกี่ยวกับไฟล์ที่ไม่มีอยู่หรือไม่สามารถอ่านได้ -v พิมพ์ทุกบรรทัด ยกเว้นบรรทัดที่มีรูปแบบ -w ค้นหานิพจน์เป็นคำ ราวกับว่ามันถูกล้อมรอบด้วย metaCharacters \< и \>.

grep -- ช่วยด้วย

การใช้งาน: grep [OPTION]... PATTERN [FILE]... ค้นหา PATTERN ในแต่ละ FILE หรืออินพุตมาตรฐาน ตามค่าเริ่มต้น PATTERN คือนิพจน์ทั่วไปแบบธรรมดา (BRE) ตัวอย่าง: grep -i "hello world" menu.h main.c การเลือกประเภทของนิพจน์ทั่วไปและการตีความ: -E, --extensed-regexp PATTERN - นิพจน์ทั่วไปแบบขยาย (ERE) -F, --fixed-regexp PATTERN - สตริงที่มีความยาวคงที่ คั่นด้วยอักขระขึ้นบรรทัดใหม่ -G, --basic-regexp PATTERN - นิพจน์ทั่วไปแบบง่าย (BRE) -P, --perl-regexp PATTERN - นิพจน์ทั่วไป Perl -e, --regexp=PATTERN ใช้ PATTERN เพื่อ ค้นหา - f, --file=FILE ใช้รูปแบบจาก FILE -i, --ignore-case ละเว้นความแตกต่างของตัวพิมพ์ -w, --word-regexp PATTERN ต้องตรงกับทุกคำ -x, --line-regexp PATTERN ต้องตรงกับทั้งบรรทัด -z, --null-data บรรทัดถูกคั่นด้วยไบต์ null แทนที่จะเป็นอักขระสิ้นสุดบรรทัด เบ็ดเตล็ด: -s, --no-messages ระงับข้อความแสดงข้อผิดพลาด -v, --revert-match เลือกบรรทัดที่ไม่ตรงกัน -V, - - เวอร์ชันที่พิมพ์ ข้อมูลเวอร์ชันและออก --help แสดงความช่วยเหลือนี้และออก --mmap สำหรับ ความเข้ากันได้แบบย้อนหลังละเว้นการควบคุมเอาต์พุต: -m, --max-count=NUMBER หยุดหลังจาก NUMBER ที่ระบุของการจับคู่ -b, --byte-offset พิมพ์ออฟเซ็ตไบต์พร้อมกับบรรทัดเอาต์พุต -n, --line-number พิมพ์บรรทัด number พร้อมกับบรรทัดเอาต์พุต --line-buffered ล้างบัฟเฟอร์หลังแต่ละบรรทัด -H, --with-filename พิมพ์ชื่อไฟล์สำหรับการจับคู่แต่ละรายการ -h, --no-filename อย่าเริ่มเอาต์พุตด้วยชื่อไฟล์ -- label=LABEL ใช้ LABEL เป็นชื่อไฟล์สำหรับอินพุตมาตรฐาน -o, --การจับคู่เท่านั้น แสดงเพียงส่วนหนึ่งของบรรทัดที่ตรงกัน PATTERN -q, --quiet, --silent ระงับเอาต์พุตปกติทั้งหมด --binary-files=TYPE ถือว่า ที่ ไฟล์ไบนารีมีประเภท: ไบนารี ข้อความ หรือไม่ตรงกัน -a, --text เช่นเดียวกับ --binary-files=text -I เช่นเดียวกับ --binary-files=without-match -d, --directories=ACTION วิธีจัดการไดเร็กทอรี ACTION can be read ), เรียกซ้ำ (เรียกซ้ำ) หรือข้าม (ข้าม) -D, --devices=ACTION วิธีจัดการอุปกรณ์, FIFO และซ็อกเก็ต ACTION สามารถอ่านหรือข้ามได้ -R, -r, --recursive เช่นเดียวกับ --directories=recurse --include=F_PATTERN ประมวลผลเฉพาะไฟล์ที่ตรงกันภายใต้ F_TEMPLATE - -exclude=F_TEMPLATE ข้ามไฟล์และไดเร็กทอรีที่ตรงกัน F_TEMPLATE --exclude-from=FILE ข้ามไฟล์ที่ตรงกับไฟล์เทมเพลตจาก FILE --exclude-dir=TEMPLATE ไดเร็กทอรีที่ตรงกับ PATTERN จะถูกข้าม -L, - -files-without-match พิมพ์เท่านั้น ชื่อไฟล์ที่ไม่ตรงกัน -l, --files-with-matches พิมพ์เฉพาะชื่อ FILE ที่ตรงกัน -c, --count พิมพ์เฉพาะจำนวนบรรทัดที่ตรงกันต่อ FILE -T, --initial-tab align tab (หากจำเป็น) - Z, --null พิมพ์ไบต์ 0 หลังชื่อ FILE การจัดการบริบท: -B, --before-context=NUM พิมพ์ NUMBER บรรทัดของบริบทก่อนหน้า -A, --after-context=NUM พิมพ์ NUMBER บรรทัดของ บริบทที่ตามมา -C, --context[=NUMBER] พิมพ์ NUMBER ของบรรทัดบริบท -NUMBER เหมือนกับ --context=NUMBER --color[=WHEN], --color[=WHEN] ใช้เครื่องหมายเพื่อแยกแยะความแตกต่างที่ตรงกัน เส้น; เมื่อสามารถเป็นได้เสมอ ไม่เคย หรือ auto -U, --binary อย่าลบอักขระ CR ที่ท้ายบรรทัด (MSDOS) -u, --unix-byte-offsets แสดงออฟเซ็ตราวกับว่าไม่มี CR-s (MSDOS) ) แทนที่จะเป็น "egrep" ควรรัน "grep -E" จะใช้ "grep -F" แทน "fgrep" เป็นการดีกว่าที่จะไม่ทำงานเป็น "egrep" หรือ "fgrep" เมื่อไม่ได้ระบุ FILE หรือเมื่อ FILE เป็น - อินพุตมาตรฐานจะถูกอ่าน หากมีการระบุน้อยกว่าสองไฟล์ ระบบจะถือว่า -h หากพบรายการที่ตรงกัน รหัสทางออกจะเป็น 0 และ 1 หากไม่ใช่ หากเกิดข้อผิดพลาดหรือหากไม่ได้ระบุตัวเลือก -q รหัสทางออกจะเป็น 2 รายงานข้อผิดพลาดไปที่: กรุณารายงานข้อผิดพลาดในการแปลไปที่: หน้าแรกของ GNU Grep: ความช่วยเหลือสำหรับการทำงานกับโปรแกรม GNU: