Bash 递归计算代码行数,包括压缩(zip)文件
我使用以下Bash脚本计算我的一个项目中的代码行数:Bash 递归计算代码行数,包括压缩(zip)文件,bash,Bash,我使用以下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
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-名称\*.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
unzip-p archive.zip'*.java'
可能会打印警告注意:文件名不匹配:*.java
如果没有.java
文件。您可以通过在find
命令之后添加2>/dev/null
来抑制这种情况
请记住,这种方法效率很低<代码>查找
必须为每个文件扩展名运行。zip文件也会被读取多次。首先筛选出所有要检查的文件,然后对所有文件运行wc-l
,然后汇总它们的行计数,这样会更快。对文件进行计数
搜索.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-名称\*.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
unzip-p archive.zip'*.java'
可能会打印警告注意:文件名不匹配:*.java
如果没有.java
文件。您可以通过在find
命令之后添加2>/dev/null
来抑制这种情况
请记住,这种方法效率很低<代码>查找
必须为每个文件扩展名运行。zip文件也会被读取多次。首先筛选出所有要检查的文件,然后对所有文件运行wc-l
,然后对它们的行数进行汇总,这样会更快。为了简化,我只要有一个只考虑如何修改行“a=find.-name\*.java-print | wc-l
”的答案就足够了,其他所有内容都会相应地出现。您可以在脚本中添加特定于zip的部分。类似于j=`find-name\*.zip-exec unzip-l{}\|grep'\.java$'| wc-l`
。为了简化,我的答案只考虑如何修改行“a=find.-name\*.java-print | wc-l
”,其他所有内容都会相应出现。您可以在脚本中添加特定于zip的部分。类似于j=`find-name\*.zip-exec unzip-l{}\|grep'\.java$''wc-l`
。谢谢!在我接受你的答案之前,我需要做一些实验和研究,因为它似乎给了我比我预期更多的数值结果。我对Bash的了解仅限于基本内容,我需要一些时间来理解您所写的内容。我已经彻底、广泛地尝试了您的解决方案。在简单的情况下,它是有效的。在非常复杂的项目中,出现了一些问题,有时报告的数字远远高于实际数字,有时即使没有代码或只有几行代码,也会报告数万行代码。我不知道为什么会发生这种情况,有些地方出了问题,但我不知道是什么。解决方法是:使用中指示的命令将所有内容解压缩到临时文件夹中,并应用问题中指示的相同计算脚本。这样一来,计数是正确的,与我预期的相等。@FrancescoGalgani感谢您的测试。我想我发现了问题所在unzip-p
接受通配符。是否在有问题的项目中,您的一个压缩源文件的名称包含*?[]
?如果是这样,可能会导致打印更多的文件。有趣的是,修复使整个程序变得更简单。我接受了你的答案:修复后,即使在复杂的项目上,计算现在也是正确的。谢谢,谢谢!在我接受你的答案之前,我需要做一些实验和研究,因为它似乎给了我比我预期更多的数值结果。我对Bash的了解仅限于基本内容,我需要一些时间来理解您所写的内容。我已经彻底、广泛地尝试了您的解决方案。在简单的情况下,它是有效的。关于非常复p