จะให้รูปแบบสำหรับบรรทัดใหม่ใน grep ได้อย่างไร?


95

จะให้รูปแบบสำหรับบรรทัดใหม่ใน grep ได้อย่างไร? บรรทัดใหม่ที่จุดเริ่มต้นบรรทัดใหม่ในตอนท้าย ไม่ใช่วิธีการแสดงออกปกติ บางอย่างเช่น \ n.


6
ยังไม่ชัดเจนว่าต้องการอะไร new line at the beginningเป็นบรรทัดว่างและnew line at endใช้กับทุกบรรทัดในไฟล์ คุณสามารถโพสต์ตัวอย่าง?
PP

2
จริงๆแล้วคุณสามารถใช้$. ค่อนข้าง จำกัด แต่ใช้ได้ในกรณีง่ายๆ
Krzysztof Jabłoński

1
gnu.org/software/grep/manual/grep.html#Usageดูรายการที่ 15
jarno

คำตอบ:


84

grep รูปแบบจะจับคู่กับแต่ละบรรทัดดังนั้นจึงไม่มีวิธีที่รูปแบบจะตรงกับบรรทัดใหม่ที่พบในอินพุต

อย่างไรก็ตามคุณจะพบบรรทัดว่างเช่นนี้:

grep '^$' file
grep '^[[:space:]]*$' file # include white spaces 

อย่างน้อย GNU grep มีอ็อพชัน -z ที่ทำให้ grep แตกบรรทัดด้วยอักขระ null แต่ก็ดูเหมือนจะไม่สนับสนุนการขึ้นบรรทัดใหม่หรือ \ n ในรูปแบบเพื่อให้ตรงกับการขึ้นบรรทัดใหม่ให้ดูรายงานข้อผิดพลาด
jarno

1
@jarno รองรับ \ n ในรูปแบบที่มีแฟ
ล็ก

92

ลองpcregrepแทนปกติgrep:

pcregrep -M "pattern1.*\n.*pattern2" filename

ตัวเลือกที่ช่วยให้มันตรงข้ามหลายบรรทัดเพื่อให้คุณสามารถค้นหาบรรทัดใหม่เป็น-M\n


22

คุณสามารถใช้วิธีนี้ ...

grep -P '^\s$' file
  • -Pใช้สำหรับนิพจน์ทั่วไป Perl (ส่วนขยายของ POSIX grep)
  • \sจับคู่อักขระช่องว่างสีขาว ถ้าตามด้วย*จะตรงกับบรรทัดว่างด้วย
  • ^ตรงกับจุดเริ่มต้นของบรรทัด $ตรงกับจุดสิ้นสุดของบรรทัด

2
-Pเป็นส่วนขยาย GNU ฉันสบายดีที่จะใช้มันเมื่อสถานการณ์เรียกร้อง (โดยทั่วไปจะเป็น lookahead / lookbehind) แต่ POSIX grep สามารถทำสิ่งนี้ได้ด้วยไฟล์[[:space:]].
jordanm

1
การจัดการ grep ของ FWIW, Solaris และ BSD (ไม่ได้ตรวจสอบคนอื่น) ทั้งสองมีย่อหน้าสำหรับ-P. GNU ค่อนข้างเป็นมาตรฐานอยู่แล้ว :)
K3 --- rnc

1
จากหน้าคู่มือ: [-P] ตัวเลือกนี้ไม่ได้รับการสนับสนุนใน FreeBSD
MariánČerný

ไม่มี [-P] สำหรับ MacOsX อย่างใดอย่างหนึ่ง: grep [-abcdDEFGHhIiJLlmnOopqRSsUVvwxZ] [-A num] [-B num] [-C [num]] [-e pattern] [-f file] [--binary-files = value] [--color [= เมื่อ]] [--colour [= เมื่อ]] [--context [= num]] [--label] [--line-buffered] [--null] [รูปแบบ] [ไฟล์. .. ]
Niccolò

@ Niccolòคุณจะต้องbrew install grepได้ GNU grep ซึ่งดีกว่าในหลาย ๆ ด้าน apple.stackexchange.com/questions/193288/…
herdrick

19

ขอขอบคุณที่ @jarno ฉันรู้เกี่ยวกับตัวเลือก -z และฉันพบว่าเมื่อใช้ GNU grep กับตัวเลือก -P ที่จับคู่กับ\nความเป็นไปได้ :)

ตัวอย่าง:

grep -zoP 'foo\n\K.*'<<<$'foo\nbar'

พิมพ์ bar


1
เยี่ยมมากโปรดทราบว่าฉันไม่ได้รับการแจ้งเตือนเกี่ยวกับ "@jarno" ในคำตอบ
jarno

3
นี่มันเยี่ยมมาก! ขอบคุณมากสำหรับการแบ่งปัน!
Alicia Tang

6

สำหรับวิธีแก้ปัญหาชั่วคราว (โดยไม่ใช้แบบพกพา-P) คุณสามารถแทนที่อักขระขึ้นบรรทัดใหม่ชั่วคราวด้วยอักขระอื่นและเปลี่ยนกลับเช่น:

grep -o "_foo_" <(paste -sd_ file) | tr -d '_'

โดยทั่วไปแล้วจะมองหาการจับคู่แบบตรงทั้งหมด_foo_โดยที่_mean \n(so __= \n\n) คุณไม่จำเป็นต้องแปลกลับโดยtr '_' '\n'แต่ละรูปแบบจะถูกพิมพ์ในบรรทัดใหม่ดังนั้นการลบ_ก็เพียงพอแล้ว


ยกโทษให้ฉันไม่รู้ แต่กำลังใช้การทดแทนกระบวนการที่ยังไม่เข้ากันได้กับ NON posix อื่นดังนั้นคุณสมบัติที่ไม่พกพา? ใน posix shell ฉันไม่สามารถทำได้<(p paste -sd_ file )?
humanityANDpeace

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