我使用以下 Bash 脚本来计算我的一个项目中的代码行数:
echo "--- CLIENT"
cd "/mypath/client"
# Count classes:
a=`find . -name *.java -print | wc -l`
echo ""
echo "Number of Java classes: $a"
# Total count:
b=`find . -name *.java -exec cat {} ; | wc -l`
echo ""
echo "Java lines: $b"
c=`find . -name *.css -exec cat {} ; | wc -l`
echo ""
echo "CSS lines: $c"
d=`find . -name *.json -exec cat {} ; | wc -l`
echo ""
echo "JSON lines: $d"
f=$((`find . -name *.h -exec cat {} ; | wc -l` + `find . -name *.m -exec cat {} ; | wc -l`))
echo ""
echo "iOS Objective-C lines: $f"
echo ""
echo "--- SERVER"
cd "/mypath/server"
# Count classes:
h=`find . -name *.java -print | wc -l`
echo ""
echo "Number of Java classes: $h"
# Total count:
i=`find . -name *.java -exec cat {} ; | wc -l`
echo ""
echo "Java lines: $i"
echo ""
echo "Total lines of code: $((b + c + d + e + f + i))"
cd ~
只要所有源代码都可以通过这种方式搜索,此脚本就可以正常工作。现在我有一个不同的用例:一些源代码仍然可以使用此脚本访问,其中一些位于压缩的zip文件中(位于"/mypath/client"的各个子文件夹中)。这些 zip 文件可以包含根目录中的源或其中的各种子文件夹中的源。
我想可以调整我的脚本以考虑计数中的压缩文件,但我不知道该怎么做。
计数文件
当您搜索.xyz
文件时,还要搜索.zip
文件并搜索其文件列表。 您可以使用zipinfo archive.zip
列出 zip 存档中的所有文件名。zipinfo
还支持通配符仅打印匹配的文件名。例如,zipinfo archive.zip '*.java'
只打印以.java
结尾的文件名。
find . -name *.java -print
-o -name *.zip -exec zipinfo -1 {} '*.java' ; |
wc -l
此命令假定文件名不包含换行符。
计数线
您可以打印压缩文件,而无需使用unzip -p archive.zip file1 file2 ...
显式提取它们。此命令还接受通配符。
顺便说一句:您可以使用函数大大简化脚本,因为find . -name *.xyz -exec cat {} ; | wc -l
通常是相同的,除了xyz
。此外,-exec cat {} +
比-exec cat {} ;
快得多。
#! /bin/bash
countLines() {
local ext=$1
find . -name "*.$ext" -exec cat {} +
-o -name *.zip -exec unzip -p {} "*.$ext" ; |
wc -l
}
for ext in java css json; do
echo "$ext lines: $(countLines "$ext")"
done
如果没有.java
文件,unzip -p archive.zip '*.java'
可能会打印警告caution: filename not matched: *.java
。您可以通过在find
命令后添加2> /dev/null
来禁止显示此命令。
请记住,这种方法效率非常低。find
必须针对每个文件扩展名运行。并且zip文件也被多次读取。首先筛选出要检查的所有文件,然后对所有文件运行wc -l
,然后汇总它们的行数会更快。