如何递归计算目录中的所有代码行?

时间:2009-08-31 17:42:20

标签: bash shell

我们有一个PHP应用程序,想要计算特定目录及其子目录下的所有代码行。我们不需要忽略评论,因为我们只是想弄清楚。

wc -l *.php 

该命令在给定目录中运行良好,但忽略子目录。我当时认为这可能有用,但它正在返回74,绝对不是这样......

find . -name '*.php' | wc -l

提供所有文件的正确语法是什么?

46 个答案:

答案 0 :(得分:2419)

<强>尝试:

find . -name '*.php' | xargs wc -l

The SLOCCount tool 也可以提供帮助。

它将为任何内容提供准确的源代码行数 你指出它的层次结构,以及一些额外的统计数据。

排序输出: find . -name '*.php' | xargs wc -l | sort

答案 1 :(得分:429)

另一个单行:

( find ./ -name '*.php' -print0 | xargs -0 cat ) | wc -l

适用于带空格的名称,只输出一个数字。

答案 2 :(得分:373)

如果使用最新版本的Bash(或ZSH),它会更简单:

wc -l **/*.php

在Bash shell中,这需要设置globstar选项,否则** glob-operator不是递归的。要启用此设置,请发出

shopt -s globstar

要使其永久化,请将其添加到其中一个初始化文件(~/.bashrc~/.bash_profile等。)。

答案 3 :(得分:290)

您可以使用为此目的而构建的cloc实用程序。它报告每种语言的每行数量,以及其中有多少是评论等.CLOC可在Linux,Mac和Windows上使用。

用法和输出示例:

$ cloc --exclude-lang=DTD,Lua,make,Python .
    2570 text files.
    2200 unique files.                                          
    8654 files ignored.

http://cloc.sourceforge.net v 1.53  T=8.0 s (202.4 files/s, 99198.6 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Javascript                    1506          77848         212000         366495
CSS                             56           9671          20147          87695
HTML                            51           1409            151           7480
XML                              6           3088           1383           6222
-------------------------------------------------------------------------------
SUM:                          1619          92016         233681         467892
-------------------------------------------------------------------------------

答案 4 :(得分:91)

在类UNIX系统上,有一个名为cloc的工具,它提供代码统计信息。

我在我们的代码库中的一个随机目录中运行它说:

      59 text files.
      56 unique files.                              
       5 files ignored.

http://cloc.sourceforge.net v 1.53  T=0.5 s (108.0 files/s, 50180.0 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C                               36           3060           1431          16359
C/C++ Header                    16            689            393           3032
make                             1             17              9             54
Teamcenter def                   1             10              0             36
-------------------------------------------------------------------------------
SUM:                            54           3776           1833          19481
-------------------------------------------------------------------------------

答案 5 :(得分:33)

您没有指定存在多少文件或所需的输出。 这是你在找什么:

find . -name '*.php' | xargs wc -l

答案 6 :(得分:21)

<强> POSIX

与此处的大多数其他答案不同,这些答案适用于任何POSIX系统,任意数量的文件以及任何文件名(除非另有说明)。

每个文件中的行:

find . -name '*.php' -type f -exec wc -l {} \;
# faster, but includes total at end if there are multiple files
find . -name '*.php' -type f -exec wc -l {} +

每个文件中的行,按文件路径

排序
find . -name '*.php' -type f | sort | xargs -L1 wc -l
# for files with spaces or newlines, use the non-standard sort -z
find . -name '*.php' -type f -print0 | sort -z | xargs -0 -L1 wc -l

每个文件中的行,按行数排序,降序

find . -name '*.php' -type f -exec wc -l {} \; | sort -nr
# faster, but includes total at end if there are multiple files
find . -name '*.php' -type f -exec wc -l {} + | sort -nr

所有文件中的总行数

find . -name '*.php' -type f -exec cat {} + | wc -l

答案 7 :(得分:21)

另一种变化:)

$ find . -name '*.php' | xargs cat | wc -l

编辑:这将给出总和,而不是逐个文件。

修改2:在.之后添加find以使其正常工作

答案 8 :(得分:19)

对我来说更常见和简单,假设你需要计算不同名称扩展名的文件(比方说也是原生文件)

wc `find . -name '*.[h|c|cpp|php|cc]'`

答案 9 :(得分:18)

令人惊讶的是,根据查找-execawk,没有答案。我们走了:

find . -type f -exec wc -l {} \; | awk '{ SUM += $0} END { print SUM }'

此代码段可查找所有文件(-type f)。要按文件扩展名查找,请使用-name

find . -name '*.py' -exec wc -l '{}' \; | awk '{ SUM += $0; } END { print SUM; }'

答案 10 :(得分:17)

有一个名为sloccount的小工具来计算目录中的代码行。应该注意的是,它比你想要的更多,因为它忽略空行/注释,按编程语言对结果进行分组并计算一些统计信息。

答案 11 :(得分:12)

你想要的是一个简单的for循环:

total_count=0
for file in $(find . -name *.php -print)
do
    count=$(wc -l $file)
    let total_count+=count
done
echo "$total_count"

答案 12 :(得分:11)

仅限来源:

wc `find`

过滤,只需使用grep

wc `find | grep .php$`

答案 13 :(得分:11)

一个简单快速的,将使用find的所有搜索/过滤功能,当文件太多(数字参数溢出)时不会失败,可以正常使用名称中带有滑稽符号的文件,不使用xargs,将无法启动无用的大量外部命令(感谢+ find的{​​{1}}。你走了:

-exec

答案 14 :(得分:10)

工具Tokei显示有关目录中代码的统计信息。 Tokei将显示文件数量,这些文件中的总行数以及按语言分组的代码,注释和空白。 Tokei还可以在Mac,Linux和Windows上使用。

Tokei的输出示例如下:

$ tokei
-------------------------------------------------------------------------------
 Language            Files        Lines         Code     Comments       Blanks
-------------------------------------------------------------------------------
 CSS                     2           12           12            0            0
 JavaScript              1          435          404            0           31
 JSON                    3          178          178            0            0
 Markdown                1            9            9            0            0
 Rust                   10          408          259           84           65
 TOML                    3           69           41           17           11
 YAML                    1           30           25            0            5
-------------------------------------------------------------------------------
 Total                  21         1141          928          101          112
-------------------------------------------------------------------------------

可以通过遵循the instructions on the README file in the repository来安装Tokei。

答案 15 :(得分:8)

猜测没有人会看到这个埋在后面......然而到目前为止,没有一个答案能解决带有空格的文件名问题。此外,如果树中的路径总长度超过shell环境大小限制(在Linux中默认为几兆字节),则使用xargs的所有内容都将失败。这是一个以非常直接的方式解决这些问题的方法。子shell使用空格处理文件。 awk总计了单个文件wc输出的流,所以永远不会用完空间。它还限制exec仅限文件(跳过目录):

find . -type f -name '*.php' -exec bash -c 'wc -l "$0"' {} \; | awk '{s+=$1} END {print s}' 

答案 16 :(得分:7)

我知道问题被标记为,但似乎您尝试解决的问题也与PHP有关。

塞巴斯蒂安·贝格曼(Sebastian Bergmann)编写了一个名为PHPLOC的工具,可以满足您的需求,并在此基础上为您提供项目复杂性的概述。这是其报告的一个例子:

Size
  Lines of Code (LOC)                            29047
  Comment Lines of Code (CLOC)                   14022 (48.27%)
  Non-Comment Lines of Code (NCLOC)              15025 (51.73%)
  Logical Lines of Code (LLOC)                    3484 (11.99%)
    Classes                                       3314 (95.12%)
      Average Class Length                          29
      Average Method Length                          4
    Functions                                      153 (4.39%)
      Average Function Length                        1
    Not in classes or functions                     17 (0.49%)

Complexity
  Cyclomatic Complexity / LLOC                    0.51
  Cyclomatic Complexity / Number of Methods       3.37

正如您所看到的,从开发人员的角度来看,所提供的信息更有用,因为它可以粗略地告诉您在开始使用项目之前项目的复杂程度。

答案 17 :(得分:5)

  

WC -L?更好地使用GREP -C ^

wc -l?的错! wc命令计算新行代码,行!当文件中的最后一行没有以新的行代码结束时,这将不计算在内!

如果您仍想要计数行,请使用 grep -c ^ ,完整示例:

#this example prints line count for all found files
total=0
find /path -type f -name "*.php" | while read FILE; do
     #you see use grep instead wc ! for properly counting
     count=$(grep -c ^ < "$FILE")
     echo "$FILE has $count lines"
     let total=total+count #in bash, you can convert this for another shell
done
echo TOTAL LINES COUNTED:  $total

最后,请注意wc -l陷阱(计数输入,而不是行!!!)

答案 18 :(得分:4)

使用zsh glob非常简单:

wc -l ./**/*.php

如果您正在使用bash,则只需升级。绝对没有理由使用bash。

答案 19 :(得分:4)

不同的东西:

wc -l `tree -if --noreport | grep -e'\.php$'`

这很好,但你需要在当前文件夹或其中一个子文件夹中至少有一个*.php文件,否则wc档位

答案 20 :(得分:4)

如果您希望结果按行数排序,则可以将| sort| sort -r-r降序排列)添加到第一个答案中,如下所示:

find . -name '*.php' | xargs wc -l | sort -r

答案 21 :(得分:4)

您可以使用名为codellink)的实用程序。这是一个简单的Python模块,用于以彩色格式计数行数。

安装

pip install codel

用法

要计算C ++文件的行数(扩展名为.cpp.h),请使用:

codel count -e .cpp .h

您还可以忽略.gitignore格式的某些文件/文件夹:

codel count -e .py -i tests/**

它将忽略tests/文件夹中的所有文件。

输出如下:

Long output

您还可以使用-s标志来缩短输出。它将隐藏每个文件的信息,并仅显示有关每个扩展名的信息。示例如下:

Short output

答案 22 :(得分:3)

首先发布最长的文件(也就是说,这些长文件需要一些重构的爱?),并排除一些供应商目录:

 find . -name '*.php' | xargs wc -l | sort -nr | egrep -v "libs|tmp|tests|vendor" | less

答案 23 :(得分:3)

如果只需要你的PHP文件中的总行数,即使在安装了GnuWin32的情况下,即使在Windows下也可以使用非常简单的一行命令。像这样:

cat `/gnuwin32/bin/find.exe . -name *.php` | wc -l

你需要指定find.exe的确切位置,否则Windows将提供FIND.EXE(来自旧的类似DOS的命令),因为它可能在环境PATH中的GnuWin32之前,并且具有不同的参数和结果。

请注意,在上面的命令中,您应该使用反引号,而不是单引号。

答案 24 :(得分:3)

对于 Windows ,简单快捷的工具 LocMetrics

答案 25 :(得分:2)

至少在OS X上,其他一些答案中列出的find + xarg + wc命令会打印&#34; total&#34;在大型列表上多次,并没有给出完整的总数。我可以使用以下命令获得.c文件的总数:

find . -name '*.c' -print0 |xargs -0 wc -l|grep -v total|awk '{ sum += $1; } END { print "SUM: " sum; }'

答案 26 :(得分:2)

如果您使用的是Linux(我认为你就是这样),我推荐使用我的工具polyglot。它比sloccountcloc快得多,而且比sloccount更有特色。

您可以使用

调用它
poly .

poly

所以它比一些复杂的bash脚本更加用户友好。

答案 27 :(得分:2)

您不需要所有这些复杂且难以记住的命令。您只需要一个名为行计数器的工具。

快速概述

这是你获得工具的方式

$ pip install line-counter

使用line命令获取当前目录下的文件计数和行数(递归)

$ line
Search in /Users/Morgan/Documents/Example/
file count: 4
line count: 839

如果您想了解更多细节,请使用line -d

$ line -d
Search in /Users/Morgan/Documents/Example/
Dir A/file C.c                                             72
Dir A/file D.py                                           268
file A.py                                                 467
file B.c                                                   32
file count: 4
line count: 839

此工具的最佳部分是,您可以像配置文件一样添加.gitignore。您可以设置规则来选择或忽略要计算的文件类型,就像您在&#39; .gitignore&#39;中所做的那样。

更多说明和用法在此处:https://github.com/MorganZhang100/line-counter

答案 28 :(得分:2)

如果你想保持简单,请切断中间人,然后用所有文件名调用wc

wc -l `find . -name "*.php"`

或者用现代语法:

wc -l $(find . -name "*.php")

只要任何目录名称或文件名中没有空格,就可以正常工作。只要你没有成千上万的文件(现代shell支持很长的命令行)。您的项目有74个文件,因此您有足够的发展空间。

答案 29 :(得分:2)

排除空行

find . -name "*.php" | xargs grep -v -c '^$' | awk 'BEGIN {FS=":"} { $cnt = $cnt + $2} END {print $cnt}'

包括空行:

find . -name "*.php" | xargs wc -l

答案 30 :(得分:2)

虽然我喜欢这个脚本,但我更喜欢这个脚本,因为它也显示了每个文件的摘要,只要总计

wc -l `find . -name "*.php"`

答案 31 :(得分:2)

我使用了这个从src-project的目录启动的内联脚本:

 for i in $(find . -type f); do rowline=$(wc -l $i | cut -f1 -d" "); file=$(wc -l $i | cut -f2 -d" "); lines=$((lines + rowline)); echo "Lines["$lines"] " $file "has "$rowline"rows."; done && unset lines

产生此输出:

Lines[75]  ./Db.h has 75rows.
Lines[143]  ./Db.cpp has 68rows.
Lines[170]  ./main.cpp has 27rows.
Lines[294]  ./Sqlite.cpp has 124rows.
Lines[349]  ./Sqlite.h has 55rows.
Lines[445]  ./Table.cpp has 96rows.
Lines[480]  ./DbError.cpp has 35rows.
Lines[521]  ./DbError.h has 41rows.
Lines[627]  ./QueryResult.cpp has 106rows.
Lines[717]  ./QueryResult.h has 90rows.
Lines[828]  ./Table.h has 111rows.

答案 32 :(得分:2)

非常简单

find /path -type f -name "*.php" | while read FILE
do
    count=$(wc -l < $FILE)
    echo "$FILE has $count lines"
done

答案 33 :(得分:1)

另一个获取所有文件总和的命令(当然是Linux)

find ./ -type f -exec wc -l {}  \; | cut -d' ' -f1 | paste -sd+ | bc

与其他答案的主要区别:

  1. 使用 find -exec
  2. 使用粘贴(带剪切)
  3. 使用 bc

答案 34 :(得分:1)

我想检查多种文件类型,并且懒得手动计算总数。所以我现在用它来一次性获得总数。

find . -name '*.js' -or -name '*.php' | xargs wc -l | grep 'total'  | awk '{ SUM += $1; print $1} END { print "Total text lines in PHP and JS",SUM }'
  

79351
  15318个
  PHP和JS 94669中的总文本行

这允许您链接要过滤的多个扩展类型。只需将它们添加到-name '*.js' -or -name '*.php'部分,并可能根据您的喜好修改otuput消息

答案 35 :(得分:1)

首先更改您想知道行数的目录。例如,如果我想知道名为sample的目录的所有文件中的行号。给'<span id="' + genId + '"></span>'; 。然后尝试命令$cd sample这将返回每个文件的行数以及最后整个目录中的行总数

答案 36 :(得分:1)

我这样做:

这里是lineCount.c文件的实现:

#include <stdio.h>
#include <string.h>
#include <stdlib.h> 

int getLinesFromFile(const char*);

int main(int argc, char* argv[]) {
   int total_lines = 0; 
   for(int i = 1; i < argc; ++i) {
       total_lines += getLinesFromFile(argv[i]); // *argv is a char*        
   }    

   printf("You have a total of %d lines in all your file(s)\n",    total_lines);
   return 0;
}


int getLinesFromFile(const char* file_name) {
    int lines = 0;
    FILE* file;
    file = fopen(file_name, "r");
    char c = ' ';
    while((c=getc(file)) != EOF) if(c == '\n') ++lines;
    fclose(file);   
    return lines;
}

现在打开命令行:

然后输入gcc lineCount.c,然后输入./a.out *.txt 这将显示目录中以.txt结尾的文件总数。

答案 37 :(得分:1)

我的Windows系统上安装了繁忙的盒子。所以这就是我所做的。

ECHO OFF
for /r %%G in (*.php) do (
busybox grep . "%%G" | busybox wc -l
) 

答案 38 :(得分:1)

$cd directory
$wc -l* | sort -nr

答案 39 :(得分:1)

如果文件太多,最好只查找总行数。

find . -name '*.php' | xargs wc -l | grep -i ' total' | awk '{print $1}'

答案 40 :(得分:1)

如果要计算已编写的LOC,则可能需要排除一些文件。

对于Django项目,您可能要忽略migrationsstatic文件夹。 对于JS项目,您可以排除所有图片或所有字体。

find . \( -path '*/migrations' -o -path '*/.git' -o -path '*/.vscode' -o -path '*/fonts' -o -path '*.png' -o -path '*.jpg' -o -path '*/.github' -o -path '*/static' \) -prune -o -type f -exec cat {} + | wc -l

用法如下:  */文件夹名称  * /。file_extension

要列出文件,请修改命令的后半部分:

find . \( -path '*/migrations' -o -path '*/.git' -o -path '*/.vscode' -o -path '*/fonts' -o -path '*.png' -o -path '*.jpg' -o -path '*/.github' -o -path '*/static' \) -prune -o --print

答案 41 :(得分:0)

Table1.Merge(Table2);

答案 42 :(得分:0)

cat \`find . -name "*.php"\` | wc -l

答案 43 :(得分:0)

这是一个使用较旧的Python(至少在Python 2.6中运行)的灵活方法,其中包含@Shizzmo可爱的一个内衬。只需在types列表中填写要在源文件夹中计算的文件类型,然后放飞:

#!/usr/bin/python

import subprocess

rcmd = "( find ./ -name '*.%s' -print0 | xargs -0 cat ) | wc -l"
types = ['c','cpp','h','txt']

sum = 0
for el in types:
    cmd = rcmd % (el)
    p = subprocess.Popen([cmd],stdout=subprocess.PIPE,shell=True)
    out = p.stdout.read().strip()
    print "*.%s: %s" % (el,out)
    sum += int(out)
print "sum: %d" % (sum)

答案 44 :(得分:0)

类似于Shizzmo's answer,但更丑陋且更准确。如果您经常使用它,请对其进行修改以适合并放入脚本中。

此示例:

  1. 正确排除不是您的代码的路径(find根本不会遍历)
  2. 过滤掉复合扩展名和其他您想忽略的文件
  3. 仅包含您指定类型的实际文件
  4. 忽略空行
  5. 总共给出一个数字
find . \! \( \( -path ./lib -o -path ./node_modules -o -path ./vendor -o -path ./any/other/path/to/skip -o -wholename ./not/this/specific/file.php -o -name '*.min.js' -o -name '*.min.css' \) -prune \) -type f \( -name '*.php' -o -name '*.inc' -o -name '*.js' -o -name '*.scss' -o -name '*.css' \) -print0 | xargs -0 cat | grep -v '^$' | wc -l

答案 45 :(得分:0)

我也可以添加另一个OS X条目,这个使用普通的旧命令与exec(我更喜欢使用xargs,因为我看到过去使用xargs的非常大的find结果集的奇怪结果)。因为这是针对OS X的,我还在过滤中添加了.h或.m文件 - 确保一直复制到最后!

find ./ -type f -name "*.[mh]" -exec wc -l {}  \; | sed -e 's/[ ]*//g' | cut -d"." -f1 | paste -sd+ - | bc