Android

คำสั่ง Grep ใน linux (ค้นหาข้อความในไฟล์)

9.Linux для Начинающих - Комманда grep и Регулярные Выражения

9.Linux для Начинающих - Комманда grep и Регулярные Выражения

สารบัญ:

Anonim

คำสั่ง grep ซึ่งย่อมาจาก "Global regular expression print" เป็นหนึ่งในคำสั่งที่มีประสิทธิภาพและใช้กันทั่วไปใน Linux

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

ในบทช่วยสอนนี้เราจะแสดงวิธีใช้คำสั่ง grep ผ่านตัวอย่างการใช้งานจริงและคำอธิบายโดยละเอียดเกี่ยวกับตัวเลือก grep GNU ทั่วไป

ไวยากรณ์คำสั่ง Grep

ก่อนที่จะเข้าสู่วิธีการใช้คำสั่ง grep เริ่มต้นด้วยการทบทวนไวยากรณ์พื้นฐาน

นิพจน์โปรแกรมอรรถประโยชน์ grep ใช้แบบฟอร์มต่อไปนี้:

grep PATTERN

รายการในวงเล็บเหลี่ยมเป็นทางเลือก

  • OPTIONS - ศูนย์หรือตัวเลือกเพิ่มเติม Grep มีตัวเลือกมากมายที่ควบคุมพฤติกรรมของมัน รูปแบบ - รูปแบบการค้นหา FILE - ชื่อไฟล์อินพุตเป็นศูนย์หรือมากกว่านั้น

เพื่อให้สามารถค้นหาไฟล์ผู้ใช้ที่รันคำสั่งต้องมีสิทธิ์อ่านเพื่อเข้าถึงไฟล์

วิธีใช้ grep เพื่อค้นหาสตริงในไฟล์

การใช้งานพื้นฐานที่สุดของคำสั่ง grep คือการค้นหาสตริง (ข้อความ) ในไฟล์

ตัวอย่างเช่นหากต้องการแสดงบรรทัดจากไฟล์ /etc/passwd ที่มี string bash คุณสามารถใช้คำสั่งต่อไปนี้:

grep bash /etc/passwd

ผลลัพธ์ควรมีลักษณะดังนี้:

root:x:0:0:root:/root:/bin/bash linuxize:x:1000:1000:linuxize:/home/linuxize:/bin/bash

หากสตริงมีช่องว่างคุณต้องใส่ในเครื่องหมายคำพูดเดี่ยวหรือคู่:

grep "Gnome Display Manager" /etc/passwd

สลับการจับคู่ (ไม่รวม)

ในการแสดงบรรทัดที่ไม่ตรงกับรูปแบบให้ใช้ตัวเลือก -v (หรือ --invert-match )

ตัวอย่างเช่นเพื่อแสดงบรรทัดจากไฟล์ /etc/passwd ที่ไม่มีสตริง nologin คุณสามารถใช้คำสั่งต่อไปนี้:

grep -v nologin /etc/passwd

root:x:0:0:root:/root:/bin/bash colord:x:124:124::/var/lib/colord:/bin/false git:x:994:994:git daemon user:/:/usr/bin/git-shell linuxize:x:1000:1000:linuxize:/home/linuxize:/bin/bash

วิธีการใช้ Grep เพื่อค้นหาสตริงในเอาต์พุตคำสั่ง

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

ตัวอย่างเช่นหากต้องการทราบว่ากระบวนการใดที่กำลังทำงานอยู่บนระบบของคุณในฐานะผู้ใช้ www-data คุณสามารถใช้คำสั่ง ps ต่อไปนี้:

ps -ef | grep www-data

www-data 18247 12675 4 16:00 ? 00:00:00 php-fpm: pool www root 18272 17714 0 16:00 pts/0 00:00:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn www-data www-data 31147 12770 0 Oct22 ? 00:05:51 nginx: worker process www-data 31148 12770 0 Oct22 ? 00:00:00 nginx: cache manager process

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

ps -ef | grep www-data | grep -v grep

www-data 18247 12675 4 16:00 ? 00:00:00 php-fpm: pool www root 18272 17714 0 16:00 pts/0 00:00:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn www-data www-data 31147 12770 0 Oct22 ? 00:05:51 nginx: worker process www-data 31148 12770 0 Oct22 ? 00:00:00 nginx: cache manager process

ค้นหาแบบเรียกซ้ำ

หากต้องการค้นหารูปแบบซ้ำ ๆ ให้ใช้ตัวเลือก -r (หรือ --recursive ) การดำเนินการนี้จะค้นหาไฟล์ทั้งหมดในไดเรกทอรีที่ระบุโดยข้ามการเชื่อมโยงที่พบซ้ำ หากต้องการติดตามลิงก์สัญลักษณ์ทั้งหมดให้ใช้ตัวเลือก -R (หรือ --dereference-recursive )

ในตัวอย่างต่อไปนี้เรากำลังค้นหาสตริง linuxize.com ในไฟล์ทั้งหมดภายในไดเรกทอรี /etc :

grep -r linuxize.com /etc

คำสั่งจะพิมพ์บรรทัดการจับคู่ที่ขึ้นต้นด้วยพา ธ เต็มไปยังไฟล์

/etc/hosts:127.0.0.1 node2.linuxize.com /etc/nginx/sites-available/linuxize.com: server_name linuxize.com www.linuxize.com;

หาก -r คุณใช้ -R ตัวเลือก grep จะทำตามลิงก์สัญลักษณ์ทั้งหมด:

grep -R linuxize.com /etc

สังเกตเห็นบรรทัดสุดท้ายของผลลัพธ์ บรรทัดนั้นไม่ได้พิมพ์ในตัวอย่างข้างต้นเนื่องจากไฟล์ภายในไดเรกทอรีที่ sites-enabled ของ Nginx เป็น symlink ไปยังไฟล์การกำหนดค่าภายในไดเรกทอรีที่มีอยู่ใน sites-available

/etc/hosts:127.0.0.1 node2.linuxize.com /etc/nginx/sites-available/linuxize.com: server_name linuxize.com www.linuxize.com; /etc/nginx/sites-enabled/linuxize.com: server_name linuxize.com www.linuxize.com;

แสดงเฉพาะชื่อไฟล์

หากต้องการระงับเอาต์พุต grep ดีฟอลต์และพิมพ์เฉพาะชื่อของไฟล์ที่มีรูปแบบที่ตรงกันคุณสามารถใช้ตัวเลือก -l (หรือ --files-with-matches )

ตัวอย่างเช่นการค้นหาไฟล์ทั้งหมดที่ลงท้ายด้วย. .conf ในไดเร็กทอรีการทำงานปัจจุบันและพิมพ์เฉพาะชื่อไฟล์ที่มีประเภทสตริง linuxize.com :

grep -l linuxize.com *.conf

ผลลัพธ์จะมีลักษณะดังนี้:

tmux.conf haproxy.conf

ตัวเลือก -l มักจะใช้ร่วมกับตัวเลือกซ้ำ -R :

grep -Rl linuxize.com /tmp

การค้นหาแบบคำนึงถึงขนาดตัวพิมพ์

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

หากต้องการละเว้นตัวพิมพ์เล็กขณะค้นหาให้ใช้ตัวเลือก -i (หรือ --ignore-case )

ตัวอย่างเช่นเมื่อค้นหา Zebra โดยไม่มีตัวเลือกใด ๆ คำสั่งต่อไปนี้จะไม่แสดงผลลัพธ์ใด ๆ เช่นมีบรรทัดที่ตรงกัน:

grep Zebra /usr/share/words

แต่ถ้าคุณทำการค้นหาแบบตัวเล็กและตัวเล็กโดยใช้ตัวเลือก -i มันจะจับคู่ตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก:

grep -i Zebra /usr/share/words

การระบุ“ Zebra” จะตรงกับ“ zebra”, “ ZEbrA” หรือการรวมกันของตัวอักษรตัวพิมพ์ใหญ่และตัวพิมพ์เล็กสำหรับสตริงนั้น

zebra zebra's zebras

ค้นหาคำเต็ม

เมื่อค้นหาคำว่า "gnu" grep จะพิมพ์บรรทัดที่ฝังคำว่า "gnu" เป็นคำขนาดใหญ่เช่น "cygnus" หรือ "magnum"

grep gnu /usr/share/words

cygnus gnu interregnum lgnu9d lignum magnum magnuson sphagnum wingnut

ในการส่งคืนเฉพาะบรรทัดเหล่านั้นที่สตริงที่ระบุเป็นทั้งคำ (ล้อมรอบด้วยอักขระที่ไม่ใช่คำ) ให้ใช้ตัวเลือก -w (หรือ --word-regexp )

อักขระใน Word ประกอบด้วยตัวอักษรและตัวเลข ( az , AZ และ 0-9 ) และขีดล่าง ( _ ) อักขระอื่น ๆ ทั้งหมดถือเป็นอักขระที่ไม่ใช่คำ

grep -w gnu /usr/share/words

gnu

แสดงหมายเลขบรรทัด

ในการแสดงจำนวนบรรทัดที่มีสตริงที่ตรงกับรูปแบบให้ใช้ตัวเลือก -n (หรือ --line-number ) เมื่อใช้ตัวเลือกนี้ grep จะพิมพ์ผลลัพธ์ที่ตรงกันไปยังเอาต์พุตมาตรฐานนำหน้าด้วยหมายเลขบรรทัดที่พบ

ตัวอย่างเช่นการแสดงบรรทัดจากไฟล์ /etc/services ที่มี string bash นำหน้าด้วยหมายเลขบรรทัดที่ตรงกันคุณสามารถใช้คำสั่งต่อไปนี้:

grep -n 10000 /etc/services

ผลลัพธ์ด้านล่างแสดงให้เราเห็นว่าการแข่งขันมีอยู่ในสาย 10423 และ 10424

10423:ndmp 10000/tcp 10424:ndmp 10000/udp

นับการแข่งขัน

หากต้องการพิมพ์จำนวนบรรทัดที่ตรงกันไปยังเอาต์พุตมาตรฐานให้ใช้ตัวเลือก -c (หรือ --count )

ในตัวอย่างด้านล่างเรากำลังนับจำนวนบัญชีที่มี /usr/bin/zsh เป็นเชลล์

grep -c '/usr/bin/zsh' /etc/passwd

4

ค้นหาหลายเงื่อนไข (รูปแบบ)

รูปแบบการค้นหาสองรูปแบบขึ้นไปสามารถเข้าร่วมโดยใช้ตัวดำเนินการ OR.

ตามค่าเริ่มต้น grep ตีความรูปแบบเป็นนิพจน์ทั่วไปพื้นฐานที่อักขระเมตาเช่น | สูญเสียความหมายพิเศษและต้องใช้เวอร์ชันแบ็กสแลช

ในตัวอย่างด้านล่างเรากำลังค้นหาคำทั้งหมดที่ fatal error และ critical ในไฟล์บันทึกข้อผิดพลาด Nginx:

grep 'fatal\|error\|critical' /var/log/nginx/error.log

grep -E 'fatal|error|critical' /var/log/nginx/error.log

โหมดเงียบ

-q (หรือ --quiet ) บอกให้ grep ไม่เขียนข้อมูลใด ๆ ลงในเทอร์มินัล (เอาต์พุตมาตรฐาน) หากพบการแข่งขันคำสั่งจะออกด้วยสถานะ 0 สิ่งนี้มีประโยชน์เมื่อใช้ grep ในเชลล์สคริปต์ที่คุณต้องการตรวจสอบว่าไฟล์มีสตริงและดำเนินการบางอย่างขึ้นอยู่กับผลลัพธ์

นี่คือตัวอย่างของการใช้ grep ในโหมดเงียบเป็นคำสั่งทดสอบในคำสั่ง if :

if grep -q PATTERN filename then echo pattern found else echo pattern not found fi

การแสดงออกปกติขั้นพื้นฐาน

GNU Grep มีชุดคุณสมบัติการแสดงออกปกติสองชุดคือพื้นฐานและขยาย โดยค่าเริ่มต้น grep ตีความรูปแบบเป็นนิพจน์ปกติพื้นฐาน

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

  • ใช้สัญลักษณ์ ^ (คาเร็ต) เพื่อจับคู่นิพจน์ที่จุดเริ่มต้นของบรรทัด ในตัวอย่างต่อไปนี้สตริงที่ ^kangaroo จะจับคู่ก็ต่อเมื่อมันเกิดขึ้นที่จุดเริ่มต้นของบรรทัด

    grep "^kangaroo" file.txt

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

    grep "kangaroo$" file.txt

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

    grep "kan..roo" file.txt

    ใช้ (วงเล็บ) เพื่อจับคู่อักขระเดี่ยวใด ๆ ที่อยู่ในวงเล็บ ตัวอย่างเช่นค้นหาบรรทัดที่มีการ accept หรือ“ accent คุณสามารถใช้รูปแบบต่อไปนี้:

    grep "accet" file.txt

    ใช้ (วงเล็บ) เพื่อจับคู่อักขระเดี่ยวใด ๆ ที่อยู่ในวงเล็บ รูปแบบต่อไปนี้จะจับคู่การรวมกันของสตริงที่มี co(any_letter_except_l)a เช่น coca , cobalt และอื่น ๆ แต่จะไม่ตรงกับบรรทัดที่มี cola

    grep "coa" file.txt

หากต้องการหลีกเลี่ยงความหมายพิเศษของอักขระต่อไปให้ใช้สัญลักษณ์ \ (แบ็กสแลช)

นิพจน์ทั่วไปที่ขยายเพิ่ม

หากต้องการตีความรูปแบบเป็นนิพจน์ทั่วไปที่ขยายให้ใช้ตัวเลือก -E (หรือ --extended-regexp ) นิพจน์ทั่วไปที่ขยายเพิ่มนั้นประกอบด้วยอักขระพื้นฐานทั้งหมดรวมถึงอักขระเพิ่มเติมเพื่อสร้างรูปแบบการค้นหาที่ซับซ้อนและมีประสิทธิภาพยิ่งขึ้น ด้านล่างเป็นตัวอย่าง:

  • จับคู่และแยกที่อยู่อีเมลทั้งหมดจากไฟล์ที่กำหนด:

    grep -E -o "\b+@+\.{2, 6}\b" file.txt

    จับคู่และแยกที่อยู่ IP ที่ถูกต้องทั้งหมดจากไฟล์ที่กำหนด:

    grep -E -o '(25|2|??)\.(25|2|??)\.(25|2|??)\.(25|2|??)' file.txt

อ็อพชัน -o ใช้เพื่อพิมพ์เฉพาะสตริงที่ตรงกัน

พิมพ์ลายเส้นก่อนการแข่งขัน

หากต้องการพิมพ์จำนวนบรรทัดที่ระบุก่อนที่จะจับคู่บรรทัดให้ใช้ตัวเลือก -B (หรือ --before-context )

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

grep -B 5 root /etc/passwd

พิมพ์เส้นหลังจากการแข่งขัน

หากต้องการพิมพ์จำนวนบรรทัดที่เฉพาะเจาะจงหลังจากจับคู่บรรทัดให้ใช้ตัวเลือก -A (หรือ --after-context )

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

grep -A 5 root /etc/passwd

ข้อสรุป

คำสั่ง grep อนุญาตให้คุณค้นหารูปแบบด้านในของไฟล์ หากพบการจับคู่ grep จะพิมพ์บรรทัดที่มีรูปแบบที่ระบุ

มีอะไรอีกมากมายให้เรียนรู้เกี่ยวกับ Grep ที่หน้าคู่มือผู้ใช้ Grep

ขั้ว grep