计数代码行?


24

如果我想计算一下代码行,那么琐碎的事情就是

cat *.c *.h | wc -l

但是,如果我有几个子目录怎么办?



3
题外话:为什么不必要catwc -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中,但不计入代码量度。(评论通常也不会算在内)
歌特尔

Answers:


49

最简单的方法是使用名为的工具cloc。使用这种方式:

cloc .

而已。:-)


1
-1,因为该程序无法识别无聊的大脑之外的语言中的代码行。它了解Ada和Pascal,C和C ++,Java和JavaScript以及“企业”类型语言,但是它拒绝仅通过文件扩展名来计算SLOC,因此对于DSL甚至是碰巧不知道的语言完全没有用。关于。

21
@cat没有什么是完美的,没有什么可以满足您过去和将来的所有需求。
Ho1

2
那么,这CLOC拒绝承认编程语言确实履行我所有的过去和未来的需求:)

6
根据CLOC文档,@ cat可以在语言定义文件中读取它,因此有一种方法可以使它识别未定义语言的代码。另外,它是开源的,因此您可以随时对其进行扩展以使其变得更好!
Centimane

39

你或许应该使用SLOCCountCLOC为此,他们正在为一个项目计算行源代码而设计的,不管目录结构等; 要么

sloccount .

要么

cloc .

将从当前目录开始生成所有源代码的报告。

如果要使用findwc,GNU wc有一个不错的--files0-from选择:

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

(感谢SnakeDocCLOC建议!)


sloccount +1。有趣的是,运行sloccount /tmp/stackexchange(在我最近一次重启后于5月17日再次创建)显示,开发发现的sh,perl,awk等文件的估计成本为$ 11,029。并且其中不包括从未将其写入脚本文件的一线文件。
cas

11
根据代码行估算成本?那么所有将意大利面重构为可维护的人呢?
停止危害莫妮卡

@OrangeDog您总是可以尝试在开销中说明这一点;请参阅文档以获取有关计算的解释(具有非常旧的薪水数据)以及可以调整的参数。
Stephen Kitt


@StephenKitt>仍然是主要问题,它在倒数。清理代码时,通常会减少行数。当然,您可以尝试手动支付其他代码的开销以解决已删除的代码,但我不认为它比首先猜测整个价格有什么好处。
频谱

10

由于该wc命令可以接受多个参数,因此您可以将所有文件名传递给wc使用GNU动作的+参数:-execfind

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

或者,在中bash,使用shell选项globstar以递归方式遍历目录:

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

默认情况下,其他shell递归遍历(例如zsh),或者具有类似的选项,例如globstar,至少大多数。


1
+1无需在我没有root的计算机上安装非标准软件
Bamboomy 18'3

5

您可以findxargs和一起使用wc

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

2
(假设文件路径中不包含空格,换行符,单引号,反斜杠字符的双引号。total如果wc调用多个s,它也可能输出几行。)
StéphaneChazelas 16

也许wc可以通过管道find传递到while read FILENAME; do . . .done结构来解决几个命令问题。并在while循环内使用wc -l。剩下的就是将总行汇总成一个变量并显示出来。
Sergiy Kolodyazhnyy

5

如果您处于无法访问cloc等的环境中,建议您

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

演练:find递归搜索名称以.c或结尾.hcat在其上运行的所有常规文件。输出通过管道传递,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-但给定的find命令是准确的递归等价cat *.[ch]


3

样品使用awk

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

用于+代替\;
乔纳森·勒夫勒

@JonathanLeffler为什么?
Hastur

1
@Hastur:它运行wc -l的文件组,而不是像xargs做,但它处理的文件名奇数球字符(如空格),而无需任何xargs或(非标准)-print0-0选项findxargs分别。这是次要的优化。不利的一面是,wc在给定多个文件的情况下,每次调用都会在末尾输出总行数- awk脚本将对此进行处理。因此,这不是灌篮,但通常,+代替\;with find是一个好主意。
乔纳森·莱夫勒

@JonathanLeffler谢谢。我同意。不过,我担心的是传递给的参数字符串的长度wc。如果先验地未知将要找到的文件数量,是否有通过该限制的风险,或者以某种方式由find处理?
Hastur

2
@Hastur:find将文件分组为方便的大小束,该束不会超出平台上参数列表的长度限制,并考虑到环境(这是从参数列表长度中得出的-因此,参数列表的长度加上环境的长度必须小于最大值)。IOW,做好find工作,就像做好工作一样xargs
乔纳森·勒夫勒

1

简单命令:

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

(假设文件路径中不包含空格,换行符,单引号,反斜杠字符的双引号。total如果wc调用多个s,它也可能输出几行。)
StéphaneChazelas 16

0

如果您使用的是Linux,则建议使用我自己的工具polyglot。它比的速度快得多,cloc并且功能强大sloccount

尽管没有提供任何二进制文件,您也应该能够在BSD上进行构建。

您可以使用

poly .

-2

find . -name \*.[ch] -print | xargs -n 1 wc -l应该可以。除此之外,还有几种可能的变体,例如使用-exec而不是将输出通过管道传递到wc


4
find . -name \*.[ch] -print不打印文件内容,仅打印文件名。所以我算一下文件的数目,不是吗?我需要`xargs'吗?
Niklas Rosencrantz

@ Programmer400是的,您将需要xargs,并且wc如果文件很多,还需要监视多次调用;您需要查找所有total行并将它们相加。
Stephen Kitt

如果您只想要总行数,则需要做find . -name \*.[ch] -print0 | xargs -0 cat | wc -l
蓬松的2016年

请注意,此(find . -name \*.[ch] -print | wc -l)计算文件数(除非文件名包含换行符-但这很不寻常)-它不计算文件中的行数。
乔纳森·勒夫勒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.