นับจำนวนบรรทัดในไฟล์


64

ฉันแน่ใจว่ามีหลายวิธีในการทำเช่นนี้ฉันจะนับจำนวนบรรทัดในไฟล์ข้อความได้อย่างไร

$ <cmd> file.txt
1020 lines

คำตอบ:


98

วิธีมาตรฐานอยู่กับwcซึ่งใช้อาร์กิวเมนต์เพื่อระบุสิ่งที่ควรนับ (ไบต์ตัวอักษรคำ ฯลฯ ); -lสำหรับสาย:

$ wc -l file.txt
1020 file.txt

ฉันจะนับจำนวนบรรทัดในแฟ้มอย่างไรหากฉันต้องการที่จะละเว้นการแสดงความเห็น? โดยเฉพาะฉันไม่ต้องการนับบรรทัดที่ขึ้นต้นด้วย +, white space บางอัน (อาจไม่ใช่ white space) จากนั้น a% ซึ่งเป็นวิธีที่บรรทัดความคิดเห็นปรากฏใน git diff ของไฟล์ MATLAB ฉันพยายามทำสิ่งนี้ด้วย grep แต่ไม่สามารถหานิพจน์ทั่วไปที่ถูกต้องได้
Gdalya

@Gdalya ฉันหวังว่าท่อต่อไปนี้จะทำเช่นนี้ (ไม่มีการทดสอบถูก cat matlab.git.diff | sed -e '/^\+[ ]*.*\%$/d' | wc -lperfomed): /regexp/dลบบรรทัดว่ามันตรงregexpและ-eเปิดเพียงพอ (IMNSHO) regexpไวยากรณ์สำหรับ
dbanet

2
ทำไมไม่ง่าย ๆgrep -v '^+ *%' matlab.git.diff | wc -l?
celtschk

@celtschk ตราบใดที่นี่เป็นเรื่องปกติในบรรทัดความคิดเห็น: เป็นไปได้หรือไม่ที่จะแก้ไขgrepคำสั่งของคุณเพื่อพิจารณาเป็นกรณีความคิดเห็นเช่น" + Hello"(สังเกตช่องว่างก่อน+)
Sopalajo de Arrierez

1
@SopalajodeArrierez: แน่นอนมันเป็นไปได้: grep -v '^ *+' matlab.git.diff | wc -l(ฉันสมมติว่าเครื่องหมายคำพูดไม่ได้หมายถึงการเป็นส่วนหนึ่งของบรรทัดฉันยังสมมติว่าทั้งสองบรรทัดที่มีและไม่มีช่องว่างด้านหน้า+จะถูกแสดงความคิดเห็นหากที่ จำเป็นต้องเว้นวรรคอย่างน้อยหนึ่งอันแทนที่ดาว*ด้วย\+หรือเพียงแค่เพิ่มช่องว่างด้านหน้าดาว) อาจแทนที่จะจับคู่ช่องว่างเท่านั้นคุณต้องการจับคู่ช่องว่างโดยพลการ [[:space:]]สำหรับเรื่องนี้แทนที่พื้นที่ที่มี โปรดทราบว่าฉันได้ลบรายการที่ตรงกัน%เนื่องจากไม่ใช่ในตัวอย่างของคุณ
celtschk

15

อย่างที่ไมเคิลพูดwc -lนั่นคือหนทางที่จะไป แต่ในกรณีที่คุณลึกลับมีbash, perlหรือawkแต่ไม่wcนี่เป็นโซลูชั่นอีกไม่กี่:

ทุบตีเท่านั้น

$ LINECT=0; while read -r LINE; do (( LINECT++ )); done < file.txt; echo $LINECT

โซลูชั่น Perl

$ perl -lne 'END { print $. }' file.txt

และอ่านได้น้อยกว่ามาก:

$ perl -lne '}{ print $.' file.txt

โซลูชั่น Awk

$  awk 'END {print NR}' file.txt

15

Steven D ลืม GNU sed:

sed -n '$=' file.txt

นอกจากนี้หากคุณต้องการการนับโดยไม่แสดงชื่อไฟล์และคุณใช้wc:

wc -l < file.txt

เพียงแค่ห่ามมัน

cat -n file.txt | tail -n 1 | cut -f1

2
หรือgrep -c '', หรือtr -dc '\n' | wc -c, หรือnl -ba -nln | tail -n 1 |sed -e 's/[^0-9].*//'... สิ่งเหล่านี้มีประโยชน์ในตัวเอง (ตรงข้ามกับสิ่งที่ต้องสร้างเพื่อสร้างโปรแกรมที่ทำมากกว่าการนับบรรทัด), อื่น ๆwc -lและบริสุทธิ์ (ba) sh?
Gilles

1
@Gilles: ฉันคิดว่าวลี "หลายวิธี" ในคำถามที่ก่อให้เกิดความท้าทายที่สตีฟและฉันเพิ่มขึ้นถึง
Dennis Williamson

1
@Gilles:sed 's/.*//' file.txt | uniq -c
Dennis Williamson

2
@Gilles: โอ้คุณหมายแรก uniq -c -w 0 file.txtและคุณสามารถcut -c -7เก็บหมายเลขได้เท่านั้น หรือ POSIXly uniq -c file.txt | awk '{c+=$1}END{print c}'เพิ่มเติมได้ที่: วิธีการเกี่ยวกับdc(แม้ว่าจะไม่ใช่ POSIX) uniq -c file.txt | cut -c -7 | sed '$alax' | dc -e '[pq]sb[+z1=blax]sa' -. bcเป็น uniq -c file.txt | cut -c -7 | sed -n ':a;${s/\n/ + /gp;b};N;ba' | bcPOSIX: คำตอบง่ายถ้าคุณถือว่าความยาวสาย จำกัดuniq -c -f 100000 file.txt:
Dennis Williamson

1
@JosipRodin: เพิ่มเครื่องหมายคำพูดแล้ว
Dennis Williamson

11

คำเตือนเมื่อใช้

wc -l

เนื่องจาก wc -l ฟังก์ชั่นโดยการนับ \ n หากบรรทัดสุดท้ายในไฟล์ของคุณไม่ได้ขึ้นบรรทัดใหม่อย่างมีประสิทธิภาพการนับบรรทัดจะถูกปิดโดย 1 (ดังนั้นการประชุมเก่าออกจากบรรทัดใหม่ที่ท้ายไฟล์ของคุณ)

เนื่องจากฉันไม่สามารถมั่นใจได้ว่าไฟล์ใดก็ตามที่ได้รับมาตามแบบแผนของการสิ้นสุดบรรทัดสุดท้ายด้วยการขึ้นบรรทัดใหม่หรือไม่ฉันขอแนะนำให้ใช้คำสั่งทางเลือกใด ๆ เหล่านี้ซึ่งจะรวมบรรทัดสุดท้ายในการนับโดยไม่คำนึงถึง newline หรือไม่

sed -n $= filename
perl -lne 'END { print $. }' filename
awk 'END {print NR}' filename
grep -c '' filename

สรุปที่ดี และยินดีต้อนรับสู่ยูนิกซ์ & ลินุกซ์
เซบาสเตียน

หืมเป็นชิ้นสุดท้ายของเส้นจริงเหรอ?
gena2x

1
ฉันแน่ใจว่ามันขึ้นอยู่กับการใช้งานของทุกคน สำหรับ 'ชิ้นสุดท้าย' มักจะเป็นบรรทัดข้อความที่บางคนไม่ได้ขึ้นบรรทัดใหม่ usecase ที่ฉันพบบ่อยที่สุดคือไฟล์ที่มีข้อความสตริงเดียวที่ไม่ได้ขึ้นบรรทัดใหม่ wc -l จะนับเป็น "0" เมื่อฉันคาดว่าจะนับเป็น "1"
pretzels1337

3

ในกรณีที่คุณทุบตีเท่านั้นและไม่มีเครื่องมือภายนอกให้ใช้งานคุณสามารถทำสิ่งต่อไปนี้ได้:

count=0
while read
do
  ((count=$count+1))
done <file.txt
echo $count

คำอธิบาย: ลูปอ่านบรรทัดอินพุตมาตรฐานทีละบรรทัด ( readเนื่องจากเราไม่ได้ทำสิ่งใดกับอินพุตอ่านต่อดังนั้นจึงไม่มีตัวแปรที่จัดเก็บไว้ใน) และเพิ่มตัวแปรcountในแต่ละครั้ง เนื่องจากการเปลี่ยนเส้นทาง ( <file.txtหลังdone), file.txtเข้ามาตรฐานสำหรับวงที่มาจาก


2

คุณสามารถใช้คำสั่งgrepดังนี้:

grep -c "^" file.txt

มันจะนับแถวจริงทั้งหมดfile.txtไม่ว่าแถวสุดท้ายจะมีอักขระ LF อยู่ที่ท้ายหรือไม่

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