grep ไฟล์ แต่แสดงหลายบรรทัดโดยรอบ?


3417

ฉันต้องการgrepสตริง แต่ยังแสดงห้าบรรทัดก่อนหน้าและห้าบรรทัดต่อไปนี้รวมถึงบรรทัดที่ตรงกัน ฉันจะทำสิ่งนี้ได้อย่างไร


3
ฉันเก็บสำเนาสคริปต์ perlของBrendan Gregg ไว้รอบ ๆ เพื่อจุดประสงค์นี้ ทำได้ดี.
Ethan Post

6
สำหรับวิธีแก้ปัญหาที่ใช้งานได้กับ Solaris ลองดูที่ลิงค์นี้
jahroy

106
man grep | grep -C 1 context:)
StvnW

20
man grep | grep -C 1 "\-C";)
Anders B

9
@StvnW ... ฉันไม่รู้ว่าจะเรียกเมตานั้น(โดยทั่วไปมากกว่าบริบท SO) หรือจะเรียกมันว่าอะไร คุณตอบคำถามด้วยการแสดงวิธีใช้คำตอบเพื่อค้นหาคำตอบ
bballdave025

คำตอบ:


4536

สำหรับBSDหรือGNU grepคุณสามารถใช้-B numเพื่อกำหนดจำนวนบรรทัดก่อนการแข่งขันและ-A numสำหรับจำนวนบรรทัดหลังการแข่งขัน

grep -B 3 -A 2 foo README.txt

-C numหากคุณต้องการหมายเลขเดียวกันของเส้นก่อนและหลังจากที่คุณสามารถใช้

grep -C 3 foo README.txt

สิ่งนี้จะแสดง 3 บรรทัดก่อนและ 3 บรรทัดหลัง


56
มันเป็นสิ่งที่ดี แต่น่าเสียดายที่ grep ของ Solaris ไม่รองรับสิ่งนั้น ดูลิงก์สำหรับโซลาริสที่: unix.com/solaris/33533-grep-display-few-lines-before-after.html
рüффп

9
ตกลง แต่ถ้าหากต้องการแสดงเอาต์พุตทุกบรรทัดหลังการแข่งขัน? grep -A0 และ grep -A-1 อย่าตัดมัน ...
g33kz0r

2
ใช้งานไม่ได้สำหรับฉันด้วยเหตุผลบางอย่างแม้ว่าจะพูดถึงในหน้าคนของฉัน
Hayri Uğur Koltuk

2
หากคุณเป็น HP-UX env จะไม่มี grep รุ่นใดที่ทำงานได้เหมือนใน Solaris สามารถใช้ลิงก์ Solaris แต่แทนที่ nawk ด้วย awk ในลิงก์นั้น
zkarthik

6
-n สำหรับหมายเลขบรรทัด แต่สำหรับ grep บางรุ่น -n # จะแสดง # เส้นรอบข้าง (เช่น -c) ด้วยหมายเลขบรรทัด นั่นเป็นทางลัดที่มีประโยชน์ที่ฉันต้องไปเมื่อต้องบริบท
Anthony DiSanti

607

-Aและ-Bจะทำงานได้ตามต้องการ-C n(สำหรับnบรรทัดบริบท) หรือเพียงแค่-n(สำหรับnบรรทัดบริบท ... ตราบเท่าที่ n คือ 1 ถึง 9)


ฉันลอง-nฟอร์แมตแล้วพบว่าใช้งานได้จนถึง9เท่านั้น เพราะ15มันส่งคืน 5 บรรทัด
Deepak Mahakale

7
@DeepakMahakale นี่อาจเกี่ยวข้องกับวิธีที่อาร์กิวเมนต์ / ตัวเลือกบรรทัดคำสั่งถูกแยกวิเคราะห์โดยโปรแกรม POSIX ตัวระบุตัวเลือกที่เป็นตัวอักษรตัวเดียว (เช่น-A, -Bหรือ-C) โดยทั่วไปตัวเลือกตัวเลือกจะตามด้วยค่า ( -o a.outเพื่อระบุไฟล์เอาต์พุตใน GCC) แต่ก็สามารถทำหน้าที่เป็นสวิตช์ / แฟล็กแบบง่าย ( -gเพื่อเปิดใช้งานข้อมูลการดีบักใน GCC) แต่ช่องว่างระหว่างตัวเลือกเป็นตัวเลือกเพื่อให้ตัวเลือกโดยไม่ต้องมีค่าก็เป็นไปได้ที่จะผสานพวกเขา ( -ABC) ซึ่งหมายความว่า-15จะถูกตีความ-1 -5(สองตัวเลือกที่แยกต่างหาก) และแทนที่-5 -1
natiiix

1
-5 เร็วกว่าทั้งสอง -A-5 -B 5. สิ่งเหล่านี้ไม่ได้มีไว้เพื่อใช้งานร่วมกัน มันจะสะอาดกว่าผู้อ่านคนอื่น ๆ ของสคริปต์ถ้าคุณเลือก -A หรือ -B หรือ -C มากกว่า -9
Eric Aldinger

76

แอ๊กชั่นการทำงานที่มีการขัดแย้งที่คล้ายกันเป็น grep -Cและยอมรับ แต่โดยปกติแล้วจะดีกว่าสำหรับการค้นหาด้วยรหัส


5
แอ๊ยังรองรับ -A -B
Shuo

Ack ดีกว่า grep หลายวิธี มันเร็วกว่าด้วยไวยากรณ์ที่ง่ายกว่า
chim

1
grep มีข้อดีของการติดตั้งโดยค่าเริ่มต้นในหลาย ๆ ระบบ
Marc Z

1
@MarcZ: จริงแล้ว grep มีแนวโน้มที่จะถูกติดตั้งตามค่าเริ่มต้นมากกว่า ack แต่ ack เป็นสคริปต์แบบพกพาแบบสแตนด์อะโลน ไม่จำเป็นต้องรวบรวมหรือติดตั้งในไดเรกทอรีระบบเช่น / usr / bin / เมื่อมีการดาวน์โหลดและวางไว้ในไดเรกทอรีที่ระบุใน $ PATH (และชุดบิตสิทธิ์ eXecute ที่ได้รับอนุญาต) มันควรจะทำงานได้ทันที (ไม่ sudo หรือรากสิทธิพิเศษจะต้องได้รับแอ๊การทำงาน.)
JL

คำถามนี้เกี่ยวกับgrepไม่แน่ใจว่าใช้เพื่อ "โฆษณา" ack(ซึ่งเป็นเครื่องมือที่ดีจริง ๆ ) เป็นความคิดที่ดี ...
MonsieurDart

39
grep astring myfile -A 5 -B 5

ที่จะ grep "myfile" สำหรับ "astring" และแสดง 5 บรรทัดก่อนและหลังการแข่งขันแต่ละครั้ง


19
"grep astring myfile -C 5" จะทำเช่นเดียวกัน
Syed Siraj Uddin

20

ปกติฉันจะใช้

grep searchstring file -C n # n for number of lines of context up and down

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

man grep

เครื่องมือ GNU จำนวนมากยังมีหน้าข้อมูลที่อาจมีข้อมูลที่เป็นประโยชน์เพิ่มเติมนอกเหนือจากหน้า man

info grep

13

ใช้ grep

$ grep --help | grep -i context
Context control:
  -B, --before-context=NUM  print NUM lines of leading context
  -A, --after-context=NUM   print NUM lines of trailing context
  -C, --context=NUM         print NUM lines of output context
  -NUM                      same as --context=NUM

คุณไม่ได้อ่านคำตอบที่ยอมรับหรือไม่? คุณเป็นเพียงการทำซ้ำสิ่งที่ได้รับการกล่าวว่าในคำถามเกือบ 10 ปี ...
Yokai

7
โอ้ฉันขอโทษ Yokai แต่ฉันไม่ได้อ่านอะไรเกี่ยวกับการ grepping ในส่วนช่วยเหลือของ grep เพื่อดึงคำตอบ
Chiel ten Brinke

1
@Yokai นอกจากสิ่งที่ Chiel ten Brinke กล่าวแล้วคำตอบที่ได้รับการยอมรับไม่ได้กล่าวถึงตัวเลือกที่ยาวนาน
user3738870

10

ค้นหา "17655" ใน "/some/file.txt" แสดงบริบท 10 บรรทัดก่อนและหลัง (โดยใช้ Awk) เอาต์พุตที่นำหน้าด้วยหมายเลขบรรทัดตามด้วยเครื่องหมายโคลอน ใช้สิ่งนี้บน Solaris เมื่อ 'grep' ไม่รองรับตัวเลือก "- [ACB]"

awk '

/17655/ {
        for (i = (b + 1) % 10; i != b; i = (i + 1) % 10) {
                print before[i]
        }
        print (NR ":" ($0))
        a = 10
}

a-- > 0 {
        print (NR ":" ($0))
}

{
        before[b] = (NR ":" ($0))
        b = (b + 1) % 10
}' /some/file.txt;

7

ripgrep

หากคุณสนใจเกี่ยวกับประสิทธิภาพการใช้งานripgrepซึ่งมีไวยากรณ์ที่คล้ายกันgrepเช่น

rg -C5 "pattern" .

-C, --context NUM- แสดงเส้น NUM ก่อนและหลังการแข่งขันแต่ละครั้ง

นอกจากนี้ยังมีพารามิเตอร์เช่น-A/ --after-contextและ/-B--before-context

เครื่องมือนี้สร้างขึ้นจากเครื่องมือ regex ของ Rustซึ่งทำให้มีประสิทธิภาพมากกับข้อมูลขนาดใหญ่


5

นี่คือโซลูชัน @Ygorในawk

awk 'c-->0;$0~s{if(b)for(c=b+1;c>1;c--)print r[(NR-c+1)%b];print;c=a}b{r[NR%b]=$0}' b=3 a=3 s="pattern" myfile

หมายเหตุ: แทนที่aและbตัวแปรด้วยจำนวนบรรทัดก่อนและหลัง

มันเป็นประโยชน์อย่างยิ่งสำหรับระบบที่ไม่สนับสนุนของ grep -A, -Bและ-Cพารามิเตอร์


4
$ grep thestring thefile -5

-5ทำให้คุณได้รับ5สายบนและด้านล่างจับคู่ 'theString' เทียบเท่ากับหรือ-C 5-A 5 -B 5


4

Grep มีตัวเลือกที่เรียกว่าContext Line Controlคุณสามารถใช้สิ่ง--contextนั้นได้ง่ายๆ

| grep -C 5

หรือ

| grep -5

ควรทำเคล็ดลับ


1

ฉันใช้เพื่อทำวิธีกะทัดรัด

grep -5 string file

นั่นคือเทียบเท่า

grep -A 5 -B 5 string file

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