shell实现代码行数统计2--java代码统计
1. 实现背景
写个这个小工具就练习下shell语法,先前写的那一版统计代码行数的,可以通过指定后缀对不同拓展名的文件进行统计。
不过,这个版本只统计java代码,可以选择是否包含文件中的空白行或者注释。
另外,是对shell用了一段时间后,有了一点更深层的认知,所以才写了这个,就是想写的看起来更规范点。
2. 实现思路
实现思路也是比较简单,对某个文件或某个目录下所有文件,使用后缀名进行过滤,然后将每个文件的行数统计出来(选择是否包含空行或注释),每个子目录算是起一个线程,递归的统计,将每个文件的统计结果写入一个文件内。最后对记录有统计的结果的文件的这一列结果数据累加求和。
3. 实现代码
#! /bin/bash
# Filename: count_java_code.sh
# Version: 2.0
# Author: xu xiaodong
# Description: count the java code that excludes comments and blank line. But, you can use -b or -c chosing whether includes blank_lines or comments
work_dir=`pwd`
root_dir=""
root_file=""
usage()
{
echo "Usage:"
echo "-f, file path e.g. /home/user/file.java"
echo "-d, directory e.g. /home/user"
echo "-b, count blank line"
echo "-c, count comments"
exit 2
}
count_blanklines=$((1<<1))
count_comments=$((1<<2))
count_default=0
#读取参数
read_param()
{
while [ ! $# -eq 0 ];do
case "$1" in
-f)
shift;
root_file=$1 && [ ! -f $root_file ] && echo "${root_file} is not file" && exit 1;
[ ${root_file##*.} != "java" ] && echo "${root_file} is not a java file" && exit 1;
shift;;
-d)
shift;
root_dir=$1;
[ ! -d $root_dir ] && echo "${root_dir} is not directory" && exit 1;
shift;;
-b)
count_default=$(( count_default | count_blanklines ));
shift;
;;
-c)
count_default=$(( count_default | count_comments ));
shift;
;;
-h|--help)
usage;
exit 0;
;;
*)
usage;
exit 1;
;;
esac
done
}
#统计指定的java文件的代码行数,通过-b 或 -c选项来选择是否统计空行或者注释
count_file()
{
num=`sed -e '/^$/ d' -e 's/[ \t]*//g' -e '/^[/*/]/d' "$1" | wc -l`
[[ $(( count_default & count_comments )) -gt 0 ]] && num=$(( num + `sed -n -e 's/[ \t]*//g' -e '/^[/*/]/p' "$1" | wc -l` ))
[[ $(( count_default & count_blanklines )) -gt 0 ]] && num=$(( num + `sed -n -e 's/[ \t]*//g' -e '/^$/p' "$1" | wc -l` ))
echo $num
}
if [ $# -eq 0 ];then
root_dir=$work_dir
else
read_param $@;
fi
if [ -n "$root_file" ];then
lines=`count_file $root_file`
echo "total: $lines, file: $root_file"
exit 0;
fi
count_line_file="${work_dir}/count_line_file.log"
touch $count_line_file
#递归的统计目录下所有java文件的代码行数
count_dir()
{
echo $1
for file in `ls $1`
do
the_file="$1/$file"
if [ -d "$the_file" ];then
count_dir "$the_file" &
elif [[ -f "$the_file" && ${the_file##*.} == "java" ]];then
lines=`count_file "$the_file"`
echo "$lines" >> $count_line_file
fi
done
wait
}
[ -n "$root_dir" ] && count_dir $root_dir;
wait
awk -v total=0 '{total+=$0} END{print "total: "total;}' $count_line_file
rm $count_line_file
另外,虽然代码声明了用bash来解释, 我还是想强调一遍,我用的语法是bash shell...