ฉันมีไฟล์ที่มีบรรทัดว่างที่ท้ายไฟล์ ฉันสามารถใช้grepเพื่อนับจำนวนบรรทัดว่างท้ายไฟล์ด้วยชื่อไฟล์ที่ถูกส่งเป็นตัวแปรในสคริปต์ได้หรือไม่
grep@MichaelJohn ชนะเพื่อความบริสุทธิ์ในหนังสือของฉัน
ฉันมีไฟล์ที่มีบรรทัดว่างที่ท้ายไฟล์ ฉันสามารถใช้grepเพื่อนับจำนวนบรรทัดว่างท้ายไฟล์ด้วยชื่อไฟล์ที่ถูกส่งเป็นตัวแปรในสคริปต์ได้หรือไม่
grep@MichaelJohn ชนะเพื่อความบริสุทธิ์ในหนังสือของฉัน
คำตอบ:
หากบรรทัดว่างอยู่ที่ท้ายเท่านั้น
grep -c '^$' myFile
หรือ:
grep -cx '' myFile
grep -cv . myFileเป็นอีกวิธีในการเขียน (สำหรับนักกอล์ฟรหัส) แต่ฉันพบวิธีแก้ไขgrepหากมีบรรทัดว่างที่ใดก็ได้ในไฟล์
grep -cv .จะนับบรรทัดที่มีเฉพาะไบต์ที่ไม่ได้สร้างอักขระที่ถูกต้อง
เพียงเพื่อความสนุกสนานบางอย่างน่ากลัว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//แต่เราจำได้ว่ามีหนึ่งเส้นมากเกินไปดังนั้นเราจึงลดความมันโดยการลบหนึ่งขึ้นบรรทัดใหม่ด้วยwc -lได้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 '
ในขณะที่คุณกำลังขอ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 ".*"ในการนับบรรทัด
ยอดเยี่ยมใช่มั้ย (-;
tac | grepที่ช่องว่างแรกที่ไม่ใช่ด้วย-m -A 42จากนั้นลบหนึ่งตัวเลือก ฉันไม่แน่ใจว่าอันไหนมีประสิทธิภาพมากกว่า แต่คุณสามารถwc -l | cut -d' ' -f1แทนการ grepping บรรทัดว่างได้หรือไม่
tac, wcและcutแต่ที่นี่ผมพยายามที่จะ จำกัด grepตัวเองให้ คุณสามารถเรียกมันว่าความวิปริตฉันเรียกมันว่ากีฬา (-;
อีก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())
$0 > ""อาจจะแตกต่างจาก$0 != ""นี้ ฉันมักจะถือว่าawkเป็นตัวดำเนินการ "ช้า" อยู่ดี (เช่นถ้าฉันรู้ว่าฉันมีชุดข้อมูลขนาดใหญ่เป็นอินพุตและการประมวลผลเป็นเวลาที่สำคัญฉันจะเห็นสิ่งที่ฉันสามารถทำได้เพื่อลดจำนวนที่awkต้องดำเนินการ - ฉัน ได้ใช้grep | awkโครงสร้างในสถานการณ์ดังกล่าว) แต่ต้องมีลักษณะอย่างรวดเร็วในสิ่งที่ผมถือว่าเป็นความหมาย POSIXฉันไม่สามารถเห็นการอ้างอิงถึงอย่างใดอย่างหนึ่งหรือstrcoll() memcmp()ฉันกำลังคิดถึงอะไร
strcoll()== สตริงจะนำมาเปรียบเทียบโดยใช้ลำดับเรียงสถานที่เฉพาะเจาะจง เปรียบเทียบกับรุ่นก่อนหน้า ฉันเป็นคนหนึ่งที่นำมันขึ้นมา ดูเพิ่มเติมaustingroupbugs.net/view.php?id=963
a <= b && a >= b a == bอุ๊ย!
awkหรือbash(สำหรับ[[ a < b ]]ผู้ประกอบการ) ใน en_US.UTF-8 สถานที่ในระบบ GNU เช่นสำหรับ①VS ②เช่น (สำหรับbashไม่มี<, >, =กลับจริงสำหรับผู้ที่) อาจเป็นข้อผิดพลาดในคำจำกัดความของสถานที่เหล่านั้นมากกว่าใน bash / awk
เพื่อนับจำนวนบรรทัดว่างต่อเนื่องที่ส่วนท้ายของไฟล์
โซลูชั่น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
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
ทางเลือกอื่น ๆPython:
ตัวอย่างอินพุต. txt:
$ cat input.txt
aaa
bbb
ccc
$ # command line
การกระทำ:
python -c 'import sys, itertools; f=open(sys.argv[1]);
lines=list(itertools.takewhile(str.isspace, f.readlines()[::-1]));
print(len(lines)); f.close()' input.txt
ผลลัพธ์:
3
https://docs.python.org/3/library/itertools.html?highlight=itertools#itertools.takewhile