相信做任何做程序开发的研发人员都会遇到一个问题,就是代码行数统计。虽然,行数统计没有实质性的意义,但是从侧面可以了解到模块或者系统开发的复杂度。
shell脚本代码行数常用命令
其实百度或者Google,大家能轻易搜索到很多脚本来进行统计,但是都不是很准确,搜索到的如下所示:
# find . -name "*.[ch]" | xargs cat | wc -l
# find . -name "*.[ch]" | xargs cat | grep -v ^$|wc -l
# wc -l `find . -name "*.[ch]"`|tail -n1
shell脚本代码行数统计主要问题
为了更好的获得精确,兼容性好的命令,做了一些简单分析,主要处理以下问题:
1)支持Windows换行符\r\n和Linux换行符\n处理(兼容性)
2)支持.c/.h文件类型(可扩展)
3)支持空行和注释符辨识(不算代码行)
4)支持#include符辨识(不算代码行)
shell脚本代码行数统计优化
# find . -name "*.[ch]" | xargs cat | tr -d '\r' | sed 's/^[ \t]*//g' | grep -v "^$" | grep -v "^/[/*]" | grep -v "^#" |wc -l
==》find . -name "*.[ch]" --- 迭代目录,寻找.c和.h结尾的代码文件,可以考虑增加.asm, .cpp, .java等语言
==》xargs cat --- 将前一个命令输出结果作为输入参数传入下一个命令
==》tr -d '\r' --- 删除\r字符,确保Windows和Linux换行符的一致性
==》sed 's/^[ \t]*//g' --- 去掉行首空格,统一辨识注释
==》grep -v "^$" --- 去掉空行
==》grep -v "^/[/*]" --- 去掉“//”和"/**/"注释行
==》grep -v "^#" --- 去掉#include行统计
==》wc -l --- 行数统计
shell脚本的储备知识
^一行的开始 ^d以开头的 ^..1 第三个为1的字符 ^字符要放在匹配的字符前面
$一行的末尾 ^$ 表示空行 ^.$匹配一行一个字符的 $字符要放在匹配的字符后面
*匹配任意个字符 包括0个字符 .表示单个字符
\可以屏蔽一个特殊的字符 \*\.pas 这里的*是特殊字符,这样就表示*.pas这个文件
逗号可以分割不同的匹配字符如[S,s]表示S或者s都可以
-表示一个范围,[1-9],[a-z],[A-Z] [1-9 A-Z a-z]任意的字符或者数字
A\{2\}B 表示A出现了2次 AAB
A\{4,\}B 表示A至少出现4次 AAAAB,AAAAAB
A\{2,4\}B 表示A出现2-4次 AAB AAAB AAAAB
[0-9]\{3\}\.[0-9]\{3\}\.[0-9]\{3\}\.[0-9]\{3\} 0-999.0-999.0-999.0-999
shell脚本的常用shell命令
1)tr命令去除空行
# cat 文件名 |tr -s '\n'
2)sed命令去除空行
# cat 文件名 |sed '/^$/d'
3)awk命令去除空行
# cat 文件名 |awk '{if($0!="")print}'
# cat 文件名 |awk '{if(length !=0) print $0}'
4)grep命令去除空行
# grep -v "^$" 文件名
5)sed删除行首空格
# sed 's/^[ \t]*//g'
说明:
第一个/的左边是s表示替换,即将空格替换为空。
第一个/的右边是表示后面的以xx开头。
中括号表示“或”,空格或tab中的任意一种。这是正则表达式的规范。
中括号右边是*,表示一个或多个。
第二个和第三个\中间没有东西,表示空
g表示替换原来buffer(缓冲区)中的,sed在处理字符串的时候并不对源文件进行直接处理,先创建一个buffer,但是加g表示对原buffer进行替换。整体的意思是:用空字符去替换一个或多个用空格或tab开头的本体字符串
6)sed删除行末空格
# sed 's/[ \t]*$//g'
和上面稍微有些不同是前面删除了^符,在后面加上了美元符,这表示以xx结尾的字符串为对象。但是要注意在KSH中,Tab并不是\t而是直接打入一个Tab就可以了。
7)sed删除所有的空格
# sed s/[[:space:]]//g
专业代码统计工具
专业代码统计工具,建议使用statsvn,安装好该工具后,结合svn可以很好的生成html报表。
生成报表命令如下:
</pre><pre name="code" class="plain"># mkdir stat
# svn log --xml -v > stat/svn.log
# java -jar ../statsvn.jar stat/svn.log . -output-dir stat
# statsvn stat/svn.log . -output-dir stat