ฉันจะนับจำนวนบรรทัดในไฟล์หลังจาก grep ตรงกันได้อย่างไร


14

ฉันพยายามนับจำนวนบรรทัดหลังจากแถวที่มีปัญหาในไฟล์ csv ฉันรู้ว่าฉันสามารถใช้grep -a #ไวยากรณ์เพื่อส่งออก # จำนวนบรรทัดหลังจากพบการแข่งขัน ฉันสนใจเฉพาะจำนวนบรรทัดที่แท้จริงเท่านั้น ฉันรู้ว่าฉันสามารถตั้งค่าจำนวนเป็น MAX_INT แล้วไพพ์ลงในไฟล์และทำการประมวลผลเพิ่มเติม

ฉันกำลังมองหาหนึ่งซับที่สั้นกระชับที่เพิ่งบอกฉันนับ

ข้อเสนอแนะใด ๆ

คำตอบ:


15
{ grep -m1 match; grep -c ''; } <file

นั่นจะใช้ได้กับ GNU grepและlseek()infile ที่มีความสามารถ ครั้งแรกgrepจะหยุดที่ 1 -match และที่สองจะ-count ทุกบรรทัดที่เหลืออยู่ในการป้อนข้อมูล

ไม่มี GNU grep:

{ sed '/match/q'; grep -c ''; } <file

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


ทั้งสองนี้ยังพิมพ์บรรทัดและที่สองบนพิมพ์ถึงคู่แรกแล้ว 0 สำหรับฉัน
123

@ User112638726 - คุณสามารถพิมพ์ผลการแข่งขันนัดแรกได้grep -m1 match >/dev/nullแน่นอน และปัญหาที่สองของคุณคือ GNU sed- มันไม่ได้รีเซ็ตออฟเซ็ตอินพุตต่อข้อมูลจำเพาะ คุณต้องใช้-uw / GNU - ซึ่งไม่ต้องการเสมอไป ฉันอาจจะชัดเจนกว่านี้ แต่ข้อสันนิษฐานของฉันคือ GNU grepและ GNU sedจะมาเป็นคู่ ฉันคิดว่าgrep -qm1สามารถใช้ทางลัดในการ/dev/nullเปลี่ยนเส้นทางได้ แต่ GNU grepทำสิ่งแปลก ๆ ด้วย-qและฉันจำไม่ได้ว่าทั้งสองทำงานร่วมกันอย่างไร
mikeserv

1
คำตอบที่ดี - แสดงให้เห็นถึงพลังของการจัดกลุ่มคำสั่งอย่างแท้จริง ผมไม่ทราบว่า แต่ฉันเดาwc -lเป็นนิด ๆ หน่อย ๆ grep -c ''ราคาถูกกว่า
Digital Trauma

1
@ DigitalTrauma - ใช่ฉันคิดว่ามัน(ในการหวนกลับ)แต่ฉันได้เขียนแล้วและมันเกือบบทกวีดังนั้นฉันคิดว่าฉันจะปล่อยให้ดีพออยู่คนเดียว และคุณก็พูดเช่นกันดังนั้นฉันจะนอนหลับง่ายในตอนนี้
mikeserv

9

นี่คือวิธีหนึ่ง

$ cat foo
aaa
bbb
ccc
ddd
eee
fff
$ awk '/^ddd/{a=FNR}END{print FNR-a}' foo
2
$

4
นี่ไม่ใช่ codegolf คุณสามารถให้รายละเอียด (FNR, END และอื่น ๆ ) ได้ไหม?
Archemar

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

1
อาจใช้เพียง NR เช่นเดียวกับไฟล์
123

6

อีกวิธีหนึ่ง - การใช้งานdcเป็นเรื่องลึกลับเล็กน้อย แต่ดูเหมือนว่าจะทำงานได้ดีที่นี่:

sed -n '/problem/=;$=' prob.txt | dc -e '??r-p'

sedค้นหาprob.txt"ปัญหา" และบรรทัดสุดท้ายและใช้=คำสั่งเพื่อส่งออกหมายเลขบรรทัดของทั้งคู่

dc อ่านค่าทั้งสองนี้ลงบนสแต็กกลับค่าย่อยและพิมพ์ส่วนต่าง


5

ทั้งหมดกับ sed (แม้ว่าทั้งสองคำสั่งด้วยไพพ์)

sed '/ddd/,$!d' file | sed -n '$='

ลบบรรทัดทั้งหมดก่อนบรรทัดจากนั้นคำสั่งถัดไปจะนับบรรทัดในไฟล์ใหม่


3

การดำเนินการนี้ควรลบทุกบรรทัดจนถึง (และรวมถึง) ปัญหาหนึ่งแล้วนับบรรทัดที่เหลืออยู่:

sed '1,/problem/d' data.txt | wc -l

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