การนับบรรทัดของรหัส?


24

ถ้าฉันต้องการนับบรรทัดของรหัสสิ่งเล็กน้อยคือ

cat *.c *.h | wc -l

แต่ถ้าฉันมีหลายไดเรกทอรีย่อยล่ะ



3
นอกหัวข้อ: ทำไมไม่จำเป็นcat? wc -l *.c *.hทำสิ่งเดียวกัน
Thomas Padron-McCarthy

5
@ ThomasPadron-McCarthy ไม่เป็นไร คุณจะต้องwc -l *.c *.h | tail -n 1ได้รับผลลัพธ์ที่คล้ายกัน
Gilles 'หยุดความชั่วร้าย'

2
โปรดทราบว่ากระสุนสมัยใหม่บางตัว (อาจเป็นมากที่สุด) (Bash v4, Zsh หรือมากกว่านั้น) ให้กลไกแบบเรียกซ้ำโดยใช้**ดังนั้นคุณจึงสามารถใช้งานwc -l **/*.{h,c}หรือคล้ายกันได้ โปรดทราบว่าใน Bash อย่างน้อยที่สุดตัวเลือกนี้ (เรียกว่าglobstar) จะถูกปิดตามค่าเริ่มต้น แต่โปรดทราบว่าในกรณีนี้โดยเฉพาะclocหรือSLOCCountเป็นตัวเลือกที่ดีกว่ามาก (นอกจากนี้ackอาจเหมาะfindสำหรับการค้นหา / แสดงรายการไฟล์ต้นฉบับได้อย่างง่ายดาย)
Kyle Strand

5
wc -l นับจำนวนบรรทัดไม่ใช่บรรทัดของรหัส บรรทัดว่าง 7000 บรรทัดจะยังคงแสดงใน wc -l แต่จะไม่นับในเมทริกโค้ด (ความคิดเห็นมักไม่นับ)
coteyr

คำตอบ:


49

clocวิธีที่ง่ายที่สุดคือการใช้เครื่องมือที่เรียกว่า ใช้วิธีนี้:

cloc .

แค่นั้นแหละ. :-)


1
-1 เนื่องจากโปรแกรมนี้ไม่มีวิธีการจดจำบรรทัดของรหัสในภาษานอกสมองที่น่าเบื่อเล็กน้อย มันรู้เกี่ยวกับภาษา Ada และ Pascal และ C และ C ++ และ Java และ JavaScript และ "enterprise" แต่มันปฏิเสธที่จะนับ SLOC โดยเพียงแค่การขยายไฟล์และไม่มีประโยชน์สำหรับ DSL หรือแม้แต่ภาษาที่มันไม่รู้ เกี่ยวกับ
แมว

21
@cat ไม่มีอะไรสมบูรณ์แบบและไม่มีอะไรสามารถตอบสนองความต้องการในอดีตและอนาคตทั้งหมดของคุณ
Ho1

2
ดีภาษาการเขียนโปรแกรมซึ่ง cloc ปฏิเสธที่จะยอมรับไม่แน่นอนตอบสนองทุกอดีตและอนาคตของฉันความต้องการ :)
แมว

6
@cat ตามเอกสาร CLOC ที่สามารถอ่านในไฟล์คำจำกัดความของภาษาดังนั้นจึงมีวิธีที่จะทำให้มันจดจำรหัสในภาษาที่ไม่ได้กำหนดไว้ ยิ่งไปกว่านั้นเป็นโอเพ่นซอร์สดังนั้นคุณสามารถขยายได้เสมอเพื่อให้ดีขึ้น!
Centimane

39

คุณอาจจะใช้SLOCCountหรือclocสำหรับสิ่งนี้พวกเขาได้รับการออกแบบมาโดยเฉพาะสำหรับการนับบรรทัดของรหัสที่มาในโครงการโดยไม่คำนึงถึงโครงสร้างไดเรกทอรี ฯลฯ ทั้ง

sloccount .

หรือ

cloc .

จะสร้างรายงานเกี่ยวกับซอร์สโค้ดทั้งหมดที่เริ่มต้นจากไดเรกทอรีปัจจุบัน

หากคุณต้องการใช้findและwcGNU wcมี--files0-fromตัวเลือกที่ดี:

find . -name '*.[ch]' -print0 | wc --files0-from=-

(ขอบคุณSnakeDocสำหรับคำแนะนำ cloc !)


+1 สำหรับ sloccount ที่น่าสนใจการรันsloccount /tmp/stackexchange(สร้างขึ้นอีกครั้งในวันที่ 17 พฤษภาคมหลังจากการรีบูทครั้งล่าสุดของฉัน) บอกว่าค่าใช้จ่ายโดยประมาณในการพัฒนาไฟล์ sh, perl, awk, etc เป็น $ 11,029 และนั่นไม่รวมถึงหนึ่ง liners ที่ไม่เคยทำให้มันกลายเป็นไฟล์สคริปต์
cas

11
การประมาณค่าใช้จ่ายตามบรรทัดรหัส? แล้วคนทุกคนที่จ้างสปาเก็ตตี้กลับมาเป็นสิ่งที่คงอยู่ได้?
หยุดทำร้ายโมนิก้า

@OrangeDog คุณสามารถลองบัญชีในค่าใช้จ่าย; ดูเอกสารประกอบสำหรับคำอธิบายของการคำนวณ (ด้วยข้อมูลเงินเดือนที่เก่ามาก) และพารามิเตอร์ที่คุณสามารถปรับแต่งได้
Stephen Kitt

5
clocเป็นสิ่งที่ดีเช่นกัน: github.com/AlDanial/cloc
SnakeDoc

@StephenKitt> ยังคงปัญหาหลักคือมันนับถอยหลัง เมื่อทำความสะอาดรหัสคุณมักจะจบลงด้วยสายน้อย แน่ใจว่าคุณสามารถลองส่งค่าใช้จ่ายเพื่อรับรหัสที่เหลือเพื่อบัญชีที่ถูกลบ แต่ฉันไม่เห็นว่ามันจะดีไปกว่าการคาดเดาราคาทั้งหมดในตอนแรก
spectras

10

เนื่องจากwcคำสั่งสามารถใช้อาร์กิวเมนต์หลายตัวคุณสามารถส่งชื่อไฟล์ทั้งหมดไปยังการwcใช้+อาร์กิวเมนต์ของการ-execกระทำของ GNU find:

find . -type f -name '*.[ch]' -exec wc -l {} +

อีกวิธีหนึ่งคือในการbashใช้ตัวเลือกเชลล์globstarเพื่อสำรวจไดเรกทอรีซ้ำ:

shopt -s globstar
wc -l **/*.[ch]

กระสุนอื่น ๆ หมุนวนซ้ำโดยค่าเริ่มต้น (เช่นzsh) หรือมีตัวเลือกที่คล้ายกันเช่นglobstarกันอย่างน้อยก็ส่วนใหญ่


1
+1 สำหรับการไม่จำเป็นต้องติดตั้งซอฟต์แวร์ที่ไม่ได้มาตรฐานบนเครื่องที่ฉันไม่มีรูท
Bamboomy

5

คุณสามารถใช้findร่วมกับxargsและwc:

find . -type f -name '*.h' -o -name '*.c' | xargs wc -l

2
(ที่ถือว่าพา ธ ของไฟล์ไม่มีช่องว่าง, บรรทัดใหม่, อัญประกาศเดี่ยว, เครื่องหมายอัญประกาศคู่ของอักขระแบ็กสแลชมันอาจส่งออกหลายtotalบรรทัดถ้าwcมีการเรียกหลายs)
Stéphane Chazelas

บางทีหลายwcปัญหาคำสั่งสามารถ addressed โดยท่อfindเพื่อwhile read FILENAME; do . . .doneโครงสร้าง wc -lและภายในการใช้ห่วงขณะ ส่วนที่เหลือคือการสรุปผลรวมของบรรทัดเป็นตัวแปรและแสดงมัน
Sergiy Kolodyazhnyy

5

หากคุณอยู่ในสภาพแวดล้อมที่คุณไม่สามารถเข้าถึงclocฯลฯ ฉันอยากจะแนะนำ

find -name '*.[ch]' -type f -exec cat '{}' + | grep -c '[^[:space:]]'

Run-through: findค้นหาไฟล์ปกติทั้งหมดที่มีชื่อลงท้ายด้วยอย่างใดอย่างหนึ่ง.cหรือ.hและรันcatบนไฟล์เหล่านั้น เอาต์พุตถูกไพพ์ผ่านgrepเพื่อนับบรรทัดที่ไม่ว่างทั้งหมด (บรรทัดที่มีอักขระที่ไม่ใช่ช่องว่างอย่างน้อยหนึ่งตัว)


4

ที่ได้รับการชี้ให้เห็นในความคิดเห็นที่cat file | wc -lเป็นไม่ได้เทียบเท่ากับwc -l fileเพราะอดีตพิมพ์เท่านั้นจำนวนในขณะที่พิมพ์หลังจำนวนและชื่อไฟล์ เช่นเดียวกันcat * | wc -lจะพิมพ์เพียงตัวเลขในขณะที่wc -l *จะพิมพ์บรรทัดข้อมูลสำหรับแต่ละไฟล์

ด้วยจิตวิญญาณแห่งความเรียบง่ายลองทบทวนคำถามที่ถามจริง:

ถ้าฉันต้องการนับบรรทัดของรหัสสิ่งเล็กน้อยคือ

cat *.c *.h | wc -l

แต่ถ้าฉันมีหลายไดเรกทอรีย่อยล่ะ

ประการแรกคุณสามารถลดความซับซ้อนของคำสั่งแม้แต่เล็กน้อยให้เป็น:

cat *.[ch] | wc -l

และในที่สุดความเทียบเท่าหลายไดเรกทอรีย่อยคือ:

find . -name '*.[ch]' -exec cat {} + | wc -l

นี้บางทีอาจจะดีขึ้นในหลาย ๆ ด้านเช่นการ จำกัด ไฟล์ที่จับคู่กับไฟล์ปกติเท่านั้น (ไม่ไดเรกทอรี) โดยการเพิ่ม-type f-but กำหนดfindคำสั่งเป็นที่แน่นอนเทียบเท่า recursive cat *.[ch]ของ


3

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

find . -name '*.[ch]' -exec wc -l {} \; |
  awk '{SUM+=$1}; END { print "Total number of lines: " SUM }'

ใช้ในสถานที่ของ+ \;
Jonathan Leffler

@JanathanLeffler ทำไม
Hastur

1
@Hastur: มันทำงานwc -lกับกลุ่มของไฟล์ค่อนข้างจะเป็นเช่นxargsนั้น แต่จัดการกับตัวอักษรคี่บอล (เช่นช่องว่าง) ในชื่อไฟล์โดยไม่จำเป็นต้องใช้อย่างใดอย่างหนึ่งxargsหรือ (ที่ไม่ได้มาตรฐาน) -print0และ-0ตัวเลือกfindและxargsตามลำดับ เป็นการเพิ่มประสิทธิภาพเล็กน้อย ข้อเสียคือการที่แต่ละการร้องขอwcจะส่งออกจำนวนบรรทัดทั้งหมดในตอนท้ายเมื่อได้รับหลายไฟล์awkสคริปต์จะจัดการกับสิ่งนั้น ดังนั้นมันไม่ใช่ dunk-dunk แต่บ่อยครั้งที่การใช้งาน+แทน\;ด้วยfindเป็นความคิดที่ดี
Jonathan Leffler

@JonathanLeffler ขอบคุณ ฉันเห็นด้วย. wcความกังวลของฉันอย่างไรเกี่ยวกับความยาวของสตริงพารามิเตอร์ที่ส่งผ่านไป หากไม่ทราบจำนวนเบื้องต้นของไฟล์ที่จะค้นพบมีความเสี่ยงที่จะผ่านขีด จำกัด นั้นหรือจะจัดการโดย find หรือไม่?
Hastur

2
@Hastur: findจัดกลุ่มไฟล์เป็นกลุ่มขนาดที่สะดวกซึ่งจะไม่เกินขีดจำกัดความยาวสำหรับรายการอาร์กิวเมนต์บนแพลตฟอร์มช่วยให้สภาพแวดล้อม (ซึ่งออกมาจากความยาวรายการอาร์กิวเมนต์ - ดังนั้นความยาวของรายการอาร์กิวเมนต์บวก ความยาวของสภาพแวดล้อมจะต้องน้อยกว่าค่าสูงสุด) IOW findทำงานถูกต้องเหมือนxargsทำงานถูกต้อง
Jonathan Leffler

1

คำสั่งง่าย:

find . -name '*.[ch]' | xargs wc -l

(ที่ถือว่าพา ธ ของไฟล์ไม่มีช่องว่าง, บรรทัดใหม่, อัญประกาศเดี่ยว, เครื่องหมายอัญประกาศคู่ของอักขระแบ็กสแลชมันอาจส่งออกหลายtotalบรรทัดถ้าwcมีการเรียกหลายs)
Stéphane Chazelas

0

หากคุณอยู่ในลินุกซ์ผมขอแนะนำเครื่องมือของตัวเองของฉันพูดได้หลายภาษา มันเป็นอย่างมากเร็วกว่าclocและอื่น ๆ featureful sloccountกว่า

คุณควรสร้าง BSD ได้เช่นกันแม้ว่าจะไม่มีไบนารีให้

คุณสามารถเรียกใช้ด้วย

poly .

-2

find . -name \*.[ch] -print | xargs -n 1 wc -lควรทำเคล็ดลับ มีรูปแบบที่เป็นไปได้หลายที่เช่นกันเช่นการใช้เป็นแทนท่อออกไป-execwc


4
แต่find . -name \*.[ch] -printไม่พิมพ์เนื้อหาของไฟล์เพียงชื่อไฟล์เท่านั้น ดังนั้นฉันจะนับจำนวนไฟล์แทนใช่ไหม ฉันต้องการ `xargs 'หรือไม่
Niklas Rosencrantz

@ Programmer400 ใช่คุณต้องการxargsและคุณต้องดูการwcเรียกใช้หลายรายการหากคุณมีไฟล์จำนวนมาก คุณจะต้องมองหาtotalเส้นทั้งหมดและรวมพวกเขา
Stephen Kitt

ถ้าคุณเพียงต้องการนับบรรทัดรวมคุณจะต้องทำfind . -name \*.[ch] -print0 | xargs -0 cat | wc -l
ปุย

โปรดทราบว่าสิ่งนี้ ( find . -name \*.[ch] -print | wc -l) นับจำนวนไฟล์ (ยกเว้นชื่อไฟล์ที่มีการขึ้นบรรทัดใหม่ - แต่มันผิดปกติมาก) - มันไม่นับจำนวนบรรทัดในไฟล์
Jonathan Leffler
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.