【发布时间】:2010-11-24 10:02:42
【问题描述】:
我们有一个 PHP 应用程序,想要计算特定目录及其子目录下的所有代码行数。
我们不需要忽略 cmets,因为我们只是想得到一个粗略的想法。
wc -l *.php
该命令适用于给定目录,但它会忽略子目录。我在想下面的评论可能有用,但它返回 74,这绝对不是这种情况......
find . -name '*.php' | wc -l
从目录中递归地输入所有文件的正确语法是什么?
【问题讨论】:
我们有一个 PHP 应用程序,想要计算特定目录及其子目录下的所有代码行数。
我们不需要忽略 cmets,因为我们只是想得到一个粗略的想法。
wc -l *.php
该命令适用于给定目录,但它会忽略子目录。我在想下面的评论可能有用,但它返回 74,这绝对不是这种情况......
find . -name '*.php' | wc -l
从目录中递归地输入所有文件的正确语法是什么?
【问题讨论】:
试试:
find . -name '*.php' | xargs wc -l
或(当文件名包含空格等特殊字符时)
find . -name '*.php' | sed 's/.*/"&"/' | xargs wc -l
The SLOCCount tool 也可能有所帮助。
它会给出准确的源代码行数 你指向的层次结构,以及一些额外的统计数据。
排序后的输出:
find . -name '*.php' | xargs wc -l | sort -nr
【讨论】:
find . -name '*.php' -o -name '*.inc' | xargs wc -l
wc会运行多次。也不会处理许多特殊文件名。
find . -name "*.php" -not -path "./tests*" | xargs wc -l
对于另一个单行:
( find ./ -name '*.php' -print0 | xargs -0 cat ) | wc -l
它适用于带有空格的名称,并且只输出一个数字。
【讨论】:
man find .. print0 和 xargs -0 让您可以对名称中包含空格或其他奇怪字符的文件进行操作
( find . \( -name '*.h' -o -name '*.cpp' \) -print0 | xargs -0 cat ) | wc -l
您可以使用专门为此目的而构建的cloc 实用程序。它报告每种语言的行数,以及其中有多少是 cmets 等。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
-------------------------------------------------------------------------------
【讨论】:
cloc 是跨平台的,因为它只是一个 Perl 脚本?
如果使用最新版本的 Bash(或 ZSH),则要简单得多:
wc -l **/*.php
在 Bash shell 中,这需要设置 globstar 选项,否则 ** glob-operator 不是递归的。要启用此设置,请发出
shopt -s globstar
要使其永久化,请将其添加到初始化文件之一(~/.bashrc、~/.bash_profile 等)。
【讨论】:
globstar to be set 才能工作。
wc -l **/*.[ch] 总共找到 15195373 行。不确定您是否认为这是“非常低的价值”。同样,您需要确保在 Bash 中启用了globstar。您可以通过shopt globstar 查询。要显式启用它,请执行shopt -s globstar。
.php 文件,它仍然会溢出ARG_MAX,因为wc 不是内置的。
find 生成的路径包含空格,则接受的答案将失败。这可以通过分别使用 print0 和 --null 与 find 和 xargs 调用来解决。
在类 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
-------------------------------------------------------------------------------
【讨论】:
choco install cloc
您没有指定有多少文件或所需的输出是什么。
这可能是您正在寻找的:
find . -name '*.php' | xargs wc -l
【讨论】:
go () { mkdir /tmp/go; [[ -f ./"$1" ]] && mv ./"$1" /tmp/go; (find ./ -type f -name "$*" -print0 | xargs -0 cat ) | wc -l; wc -l /tmp/go/*; mv /tmp/go/* . } 结果接近 *.py 的 slocount,但它不知道 *.js,@ 987654325@.
另一种变化:)
$ find . -name '*.php' | xargs cat | wc -l
这将给出总和,而不是逐个文件。
在find 之后添加. 以使其工作。
【讨论】:
$ find -name \*\.php -print0 | xargs -0 cat | wc -l
find . -name '*.php' | xargs cat | wc -l ... 而这给出了一个文件一个文件和一个总数:find . -name '*.php' | xargs wc -l
使用find 的-exec 和awk。我们开始:
find . -type f -exec wc -l {} \; | awk '{ SUM += $0} END { print SUM }'
这个 sn-p 查找所有文件 (-type f)。要按文件扩展名查找,请使用-name:
find . -name '*.py' -exec wc -l '{}' \; | awk '{ SUM += $0; } END { print SUM; }'
【讨论】:
find . -name '*.c' -print0 |xargs -0 wc -l 则为 1.5 秒。也就是说,这种更快的方法(至少在 OS X 上)最终会打印“总计”多次,因此需要进行一些额外的过滤才能获得正确的总计(我在答案中发布了详细信息)。
cat 的形式上执行 wc 很慢,因为系统首先必须处理所有 GB 才能开始计算行数(使用 200GB 的 jsons、12k 文件进行测试)。先做wc 然后计算结果要快得多
find . -type f -exec wc -l {} \+ 或find . -name '*.py' -type f -exec wc -l {} \+,它会在输出的末尾打印一个总数。如果您只对总数感兴趣,那么您可以更进一步并使用tail:find . -type f -exec wc -l {} \+ | tail -1 或find . -name '*.py' -type f -exec wc -l {} \+ | tail -1
对我来说更常见和简单,假设您需要计算不同扩展名的文件(比如,也是本地人):
wc $(find . -type f | egrep "\.(h|c|cpp|php|cc)" )
【讨论】:
$()
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
【讨论】:
有一个叫做sloccount 的小工具可以计算目录中的代码行数。
应该注意,它做的比你想要的更多,因为它忽略空行/cmets,按编程语言对结果进行分组并计算一些统计数据。
【讨论】:
工具Tokei 显示有关目录中代码的统计信息。 Tokei 将显示文件数、这些文件中的总行数以及按语言分组的代码、cmets 和空白。 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。
【讨论】:
你想要一个简单的for 循环:
total_count=0
for file in $(find . -name *.php -print)
do
count=$(wc -l $file)
let total_count+=count
done
echo "$total_count"
【讨论】:
xargs 的答案相比,这不是矫枉过正吗?
IFS=$'\n' 至少可以为除名称中带有换行符的文件之外的所有文件修复它。其次,你没有引用'*.php',所以它会被shell扩展而不是find,并且ergo实际上不会在子目录中找到任何php文件。 -print 也是多余的,因为它隐含在没有其他操作的情况下。
【讨论】:
一个简单的快速的,将使用find 的所有搜索/过滤功能,当文件太多时不会失败(数字参数溢出),可以很好地处理名称中带有有趣符号的文件,没有使用xargs,并且不会启动大量无用的外部命令(感谢+ for find's -exec)。给你:
find . -name '*.php' -type f -exec cat -- {} + | wc -l
【讨论】:
\; 而不是+,因为我不知道),这个答案应该是正确的答案。
cat,而\+ 版本将在一次调用中将找到的所有文件提供给cat。 -- 是标记选项的结束(这里有点不必要)。
我知道该问题被标记为bash,但您尝试解决的问题似乎也与 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
如您所见,从开发人员的角度来看,所提供的信息要有用得多,因为它可以在您开始使用项目之前大致告诉您项目的复杂程度。
【讨论】:
到目前为止,没有一个答案涉及文件名带有空格的问题。
此外,如果树中路径的总长度超过 shell 环境大小限制(在 Linux 中默认为几兆字节),则所有使用 xargs 的对象都会失败。
这是一个以非常直接的方式解决这些问题的方法。子shell 负责处理带有空格的文件。 awk 总计单个文件 wc 输出的流,因此它永远不会耗尽空间。它还将exec 限制为仅文件(跳过目录):
find . -type f -name '*.php' -exec bash -c 'wc -l "$0"' {} \; | awk '{s+=$1} END {print s}'
【讨论】:
如果您想保持简单,请去掉中间人,只需使用所有文件名调用 wc:
wc -l `find . -name "*.php"`
或者用现代语法:
wc -l $(find . -name "*.php")
只要目录名或文件名中没有空格,此方法就有效。只要您没有数以万计的文件(现代 shell 支持非常长的命令行)。您的项目有 74 个文件,因此您有足够的发展空间。
【讨论】:
wc -l `find . -type f \( -name "*.cpp" -o -name "*.c" -o -name "*.h" \) -print`
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 of '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 陷阱(输入计数,而不是行!!!)
【讨论】:
grep -c ^,您正在计算incomplete lines 的数量,这样不完整的行不能出现在text file 中。
find -type f -name '*.php' -print0 | xargs -0 grep -ch ^ | paste -sd+ - | bc 请参阅此处了解bc 的替代品:stackoverflow.com/q/926069/2400328
首先给出最长的文件(即,这些长文件可能需要一些重构的爱?),并排除一些供应商目录:
find . -name '*.php' | xargs wc -l | sort -nr | egrep -v "libs|tmp|tests|vendor" | less
【讨论】:
对于 Windows,一个简单快捷的工具是 LocMetrics。
【讨论】:
您可以使用名为codel (link) 的实用程序。这是一个简单的 Python 模块,可以用彩色格式计算行数。
pip install codel
要计算 C++ 文件的行数(带有 .cpp 和 .h 扩展名),请使用:
codel count -e .cpp .h
你也可以忽略一些 .gitignore 格式的文件/文件夹:
codel count -e .py -i tests/**
它将忽略tests/文件夹中的所有文件。
输出如下:
您还可以使用-s 标志缩短输出。它将隐藏每个文件的信息并仅显示有关每个扩展名的信息。示例如下:
【讨论】:
如果您希望您的结果按行数排序,您只需将| sort 或| sort -r(-r 用于降序排列)添加到第一个答案,如下所示:
find . -name '*.php' | xargs wc -l | sort -r
【讨论】:
xargs wc -l 的输出是数字,因此实际上需要使用sort -n 或sort -nr。
很简单:
find /path -type f -name "*.php" | while read FILE
do
count=$(wc -l < $FILE)
echo "$FILE has $count lines"
done
【讨论】:
【讨论】:
【讨论】:
至少在 OS X 上,其他一些答案中列出的 find+xarg+wc 命令在大型列表中多次打印“total”,并且没有给出完整的总数。我能够使用以下命令获得 .c 文件的单个总数:
find . -name '*.c' -print0 |xargs -0 wc -l|grep -v total|awk '{ sum += $1; } END { print "SUM: " sum; }'
【讨论】:
grep total 而不是grep -v total - 它将对wc 给出的中间和求和。重新计算中间和没有意义,因为wc 已经这样做了。
如果文件太多,最好只查找总行数。
find . -name '*.php' | xargs wc -l | grep -i ' total' | awk '{print $1}'
【讨论】:
如果你只需要总行数,比方说,你的 PHP 文件,如果你安装了 GnuWin32,即使在 Windows 下你也可以使用非常简单的一行命令。像这样:
cat `/gnuwin32/bin/find.exe . -name *.php` | wc -l
您需要指定 find.exe 的确切位置,否则将执行 Windows 提供的 FIND.EXE(来自旧的类似 DOS 的命令),因为它可能在环境 PATH 中的 GnuWin32 之前并且具有不同的参数和结果。
请注意,在上面的命令中,您应该使用反引号,而不是单引号。
【讨论】:
虽然我喜欢这些脚本,但我更喜欢这个脚本,因为它还显示每个文件的摘要,只要总数:
wc -l `find . -name "*.php"`
【讨论】: