นับจำนวนบรรทัดว่างที่ท้ายไฟล์


11

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


การนับจำนวนบรรทัดว่างติดกัน ?
RomanPerekhrest

2
@ RomanPerekhrest ฉันจะบอกอย่างนั้นมิฉะนั้นพวกเขาจะไม่เป็น "ในตอนท้ายของไฟล์"?
Sparhawk

'grep -cv -P' \ S 'filename' จะนับจำนวนบรรทัดว่างทั้งหมดในไฟล์ จำนวนท้ายที่สุดคือการเดินทางโดยรถแท็กซี่สมองของฉัน!
MichaelJohn

OP ขอgrep@MichaelJohn ชนะเพื่อความบริสุทธิ์ในหนังสือของฉัน
bu5hman

2
@ bu5hman แต่ (ตามที่เขายอมรับ) ไม่ตอบคำถาม ไม่ทำของคุณจริงๆ
Sparhawk

คำตอบ:


11

หากบรรทัดว่างอยู่ที่ท้ายเท่านั้น

grep  -c '^$' myFile

หรือ:

grep -cx '' myFile

พ่ายแพ้ต่อการแก้ไขในไม่กี่วินาที, dammit
bu5hman

grep -cv . myFileเป็นอีกวิธีในการเขียน (สำหรับนักกอล์ฟรหัส) แต่ฉันพบวิธีแก้ไขgrepหากมีบรรทัดว่างที่ใดก็ได้ในไฟล์
Philippos

2
@Philippos grep -cv .จะนับบรรทัดที่มีเฉพาะไบต์ที่ไม่ได้สร้างอักขระที่ถูกต้อง
Stéphane Chazelas

11

เพียงเพื่อความสนุกสนานบางอย่างน่ากลัวsed:

#!/bin/sh
sed '/./!H;//h;$!d;//d;x;s/\n//' "$1" | wc -l

คำอธิบาย:

  • /./บรรทัดที่อยู่ด้วยตัวละครใด ๆ ดังนั้น/./!ที่อยู่บรรทัดที่ไม่ว่างเปล่า; สำหรับHคำสั่งเหล่านั้นผนวกเข้ากับพื้นที่พัก ดังนั้นหากสำหรับแต่ละบรรทัดว่างเราได้เพิ่มหนึ่งบรรทัดในพื้นที่พักสายจะมีอีกหนึ่งบรรทัดมากกว่าจำนวนบรรทัดว่าง เราจะดูแลในภายหลัง
  • //hรูปแบบที่ว่างเปล่าตรงกับการแสดงออกปกติครั้งสุดท้ายซึ่งเป็นตัวละครใด ๆ ดังนั้นบรรทัดที่ไม่ว่างจะได้รับการแก้ไขและย้ายไปยังพื้นที่พักโดยhคำสั่งเพื่อ "รีเซ็ต" บรรทัดที่รวบรวมไว้ที่ 1 เมื่อบรรทัดว่างถัดไปจะถูกต่อท้าย จะมีอีกสองครั้งตามที่คาดไว้
  • $!dหยุดสคริปต์โดยไม่มีเอาต์พุตสำหรับทุก ๆ ยกเว้นบรรทัดสุดท้ายดังนั้นคำสั่งเพิ่มเติมจะถูกดำเนินการหลังจากบรรทัดสุดท้ายเท่านั้น ดังนั้นเส้นว่างใด ๆ ที่เราเก็บในพื้นที่พักจะอยู่ท้ายไฟล์ ดี.
  • //d: dคำสั่งจะถูกดำเนินการอีกครั้งสำหรับบรรทัดที่ไม่ว่างเปล่าเท่านั้น ดังนั้นหากบรรทัดสุดท้ายไม่ว่างเปล่าsedจะออกโดยไม่มีเอาต์พุตใด ๆ เส้นศูนย์ ดี.
  • x การแลกเปลี่ยนถือพื้นที่และพื้นที่รูปแบบดังนั้นบรรทัดที่รวบรวมอยู่ในพื้นที่รูปแบบที่จะดำเนินการในขณะนี้
  • s/\n//แต่เราจำได้ว่ามีหนึ่งเส้นมากเกินไปดังนั้นเราจึงลดความมันโดยการลบหนึ่งขึ้นบรรทัดใหม่ด้วย
  • Voila! จำนวนบรรทัดตรงกับจำนวนบรรทัดว่างที่ท้าย (โปรดทราบว่าบรรทัดแรกจะไม่ว่างเปล่า แต่ใครสนใจ) ดังนั้นเราจึงสามารถนับwc -lได้

8

GNU tac/ tail -rตัวเลือกเพิ่มเติม:

tac file | awk 'NF{exit};END{print NR?NR-1:0}'

หรือ:

tac file | sed -n '/[^[:blank:]]/q;p' | wc -l

โปรดทราบว่าในผลลัพธ์ของ:

printf 'x\n '

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

POSIXly:

awk 'NF{n=NR};END{print NR-n}' < file

แต่นั่นหมายถึงการอ่านไฟล์เต็ม ( tail -r/ tacจะอ่านไฟล์ย้อนกลับจากจุดสิ้นสุดของไฟล์ที่ค้นหาได้) ที่จะช่วยให้การส่งออกของ1printf 'x\n '


6

ในขณะที่คุณกำลังขอgrepวิธีแก้ปัญหาฉันเพิ่มอันนี้อาศัยเฉพาะ GNU grep(โอเคใช้ไวยากรณ์เชลล์และecho... ):

#!/bin/sh
echo $(( $(grep -c "" "$1") - $(grep -B$(grep -cv . "$1") . "$1" |grep -c "") ))

ฉันกำลังทำอะไรที่นี่ $(grep -c ".*" "$1")นับทุกบรรทัดในไฟล์จากนั้นเราจะแทนที่ไฟล์โดยไม่มีบรรทัดว่างต่อท้าย

และวิธีการรับเหล่านั้น $(grep -B42 . "$1"จะ grep บรรทัดที่ไม่ว่างเปล่าทั้งหมดและ 42 บรรทัดก่อนหน้าดังนั้นจึงพิมพ์ทุกอย่างจนกระทั่งบรรทัดที่ไม่ว่างสุดท้ายตราบใดที่มีบรรทัดว่างที่ต่อเนื่องกันไม่เกิน 42 บรรทัดก่อนบรรทัดว่างเปล่า เพื่อหลีกเลี่ยงข้อ จำกัด นั้นฉันรับ$(grep -cv . "$1")เป็นพารามิเตอร์สำหรับ-Bตัวเลือกซึ่งเป็นจำนวนบรรทัดว่างทั้งหมดดังนั้นใหญ่พอเสมอ ด้วยวิธีนี้ฉันได้ตัดเส้นบรรทัดว่างเปล่าที่ต่อท้ายและสามารถใช้|grep -c ".*"ในการนับบรรทัด

ยอดเยี่ยมใช่มั้ย (-;


+1 เพราะถึงแม้ว่ามันจะเป็นรหัสที่น่ากลัวก็ตอบคำถามทางเทคนิคตามที่ถามและฉันไม่สามารถทนที่จะทำเครื่องหมายลง ;-)
roaima

Grepmeister เราไม่คู่ควร
bu5hman

+1 สำหรับความวิปริต ตัวเลือกอื่น (อาจเร็วกว่านี้) คือไปtac | grepที่ช่องว่างแรกที่ไม่ใช่ด้วย-m -A 42จากนั้นลบหนึ่งตัวเลือก ฉันไม่แน่ใจว่าอันไหนมีประสิทธิภาพมากกว่า แต่คุณสามารถwc -l | cut -d' ' -f1แทนการ grepping บรรทัดว่างได้หรือไม่
Sparhawk

ใช่แน่ใจว่าคุณสามารถทำสิ่งต่างๆมากมายด้วยtac, wcและcutแต่ที่นี่ผมพยายามที่จะ จำกัด grepตัวเองให้ คุณสามารถเรียกมันว่าความวิปริตฉันเรียกมันว่ากีฬา (-;
Philippos

5

อีกawkวิธีการแก้ปัญหา ชุดรูปแบบนี้รีเซ็ตตัวนับkทุกครั้งที่มีบรรทัดที่ไม่ว่าง จากนั้นทุกบรรทัดจะเพิ่มตัวนับ (ดังนั้นหลังจากบรรทัดความยาวที่ไม่ว่างแรก, k==0.) ในตอนท้ายเราจะแสดงจำนวนบรรทัดที่เรานับ

เตรียมไฟล์ข้อมูล

cat <<'X' >input.txt
aaa

bbb
ccc



X

นับบรรทัดว่างต่อท้ายในตัวอย่าง

awk 'NF {k=-1}; {k++}; END {print k+0}' input.txt
3

ในคำนิยามนี้บรรทัดว่างอาจมีช่องว่างหรืออักขระว่างอื่น ๆ มันยังว่างเปล่า ถ้าคุณอยากจะนับบรรทัดว่างมากกว่าบรรทัดว่างเปลี่ยนแปลงสำหรับNF$0 != ""


ทำไม$0 > ""? ที่ใช้strcoll()ซึ่งจะมีประสิทธิภาพน้อยกว่า$0 != ""ที่ใช้memcmp()ในการใช้งานจำนวนมาก (POSIX เคยใช้เพื่อต้องการใช้strcoll())
Stéphane Chazelas

@ StéphaneChazelasฉันไม่คิดว่า$0 > ""อาจจะแตกต่างจาก$0 != ""นี้ ฉันมักจะถือว่าawkเป็นตัวดำเนินการ "ช้า" อยู่ดี (เช่นถ้าฉันรู้ว่าฉันมีชุดข้อมูลขนาดใหญ่เป็นอินพุตและการประมวลผลเป็นเวลาที่สำคัญฉันจะเห็นสิ่งที่ฉันสามารถทำได้เพื่อลดจำนวนที่awkต้องดำเนินการ - ฉัน ได้ใช้grep | awkโครงสร้างในสถานการณ์ดังกล่าว) แต่ต้องมีลักษณะอย่างรวดเร็วในสิ่งที่ผมถือว่าเป็นความหมาย POSIXฉันไม่สามารถเห็นการอ้างอิงถึงอย่างใดอย่างหนึ่งหรือstrcoll() memcmp()ฉันกำลังคิดถึงอะไร
roaima

strcoll()== สตริงจะนำมาเปรียบเทียบโดยใช้ลำดับเรียงสถานที่เฉพาะเจาะจง เปรียบเทียบกับรุ่นก่อนหน้า ฉันเป็นคนหนึ่งที่นำมันขึ้นมา ดูเพิ่มเติมaustingroupbugs.net/view.php?id=963
Stéphane Chazelas

@ StéphaneChazelasการดำเนินงานที่ไม่จำเป็นต้องเหมือนกับa <= b && a >= b a == bอุ๊ย!
roaima

นั่นคือกรณีของ GNU awkหรือbash(สำหรับ[[ a < b ]]ผู้ประกอบการ) ใน en_US.UTF-8 สถานที่ในระบบ GNU เช่นสำหรับVS เช่น (สำหรับbashไม่มี<, >, =กลับจริงสำหรับผู้ที่) อาจเป็นข้อผิดพลาดในคำจำกัดความของสถานที่เหล่านั้นมากกว่าใน bash / awk
Stéphane Chazelas

2

เพื่อนับจำนวนบรรทัดว่างต่อเนื่องที่ส่วนท้ายของไฟล์

โซลูชั่นSolid awk+ tac:

ตัวอย่างinput.txt:

$ cat input.txt
aaa

bbb
ccc



$  # command line 

การกระทำ:

awk '!NF{ if (NR==++c) { cnt++ } else exit }END{ print int(cnt) }' <(tac input.txt)
  • !NF- ตรวจสอบให้แน่ใจว่าบรรทัดปัจจุบันว่างเปล่า (ไม่มีฟิลด์)
  • NR==++c- สร้างความมั่นใจในลำดับบรรทัดว่างที่ต่อเนื่องกัน ( NR- จำนวนบันทึก++c- เคาน์เตอร์เสริมที่เพิ่มขึ้นอย่างเท่าเทียมกัน)
  • cnt++- ตัวนับของบรรทัดว่าง

ผลลัพธ์:

3

1

IIUC สคริปต์ต่อไปนี้ที่เรียกว่าcount-blank-at-the-end.shจะทำงาน:

#!/usr/bin/env sh

count=$(tail -n +"$(grep . "$1" -n | tail -n 1 | cut -d: -f1)" "$1" | wc -l)
num_of_blank_lines=$((count - 1))

printf "%s\n" "$num_of_blank_lines"

ตัวอย่างการใช้งาน:

$ ./count-blank-at-the-end.sh FILE
4

ผมทดสอบในGNU bash, และในAndroid mkshksh


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