bash脚本之代码统计

shell代码统计


# 代码行数: 开头不以#开头,且不为空行都算作一行代码
# 注释行数: 以#开头或者空格加上#号的都算作注释 e.g echo yestoday  #go home

# 传参:传入文件名
# 返回:代码行数 注释行数
count_line(){
    local code_lines=0 comm_lines=0
    
    while read line; do
        if echo "$line" | tr -d [:space:] | grep ^[^#]; then    #过滤空白行,且匹配不以#开头的行
            ((code_lines += 1))
            if echo "$line" | grep -E *[[:space:]]# ; then     #代码行也会有注释,就像这行
                ((comm_lines += 1))
            fi
        else
            if [ -n "$(echo "$line" | tr -d [:space:])" ]; then
                ((comm_lines += 1))
            fi
        fi
    done < $1
    
    echo $code_lines $comm_lines
}

注解:

  • grep的选项E表示ERE也就是扩展正则表达式,相对应的就是默认的BRE了(基本正则表达式)。sed是基于BRE,gawk基于ERE,那扩展表达式在哪些语法方面增强了呢?代码中的[:space:]又代表什么呢?
    • ERE相较于BRE增强的地方:?(表示前面的字符可以出现0次或1次) | +(表示前面的字符至少出现1次) | 花括号(限定前面字符出现的次数) | 管道符号(多个匹配模式) | 表达式分组(将多个字符拼合在一起,视作一个字符)
    • 特殊字符组: upper(大写) | lower(小写) | digit(数字) | alpha(字母) | alnum(字母数字) | punct(标点符号) | print(打印字符) | blank(空格或制表符) | space(任意空白字符)
  • tr也就是translate,用来置换,常用的比如 echo "WELCOME HOME, LILY" | tr [:upper:] [:lower:] 得到 welcome home, lily。tr的d选项表示替换成空白,也就等同于删除了。
  • (())用来做int的计算。
  • 然后要说的就是我们常常看到的 while read line; do {list}; done < filename 形式的读入文本了。

扩展:计算代码字数和注释字数


下面做个扩展,也就是计算代码字数,和注释字数。先测试下汉字的字数能否正常得到。

c=我在天安门
echo ${#c}
5

貌似正常,我的系统是基于ubuntu的mint发行版,其他的发行版表现会怎样就不得而知了。进入正题,要得到代码字数需要以下步骤:

  1. 截取代码区: code=${line%%[[:space:]]#*}, 截取代码行的注释区: comm=${line#*[[:space:]]#}
  2. 过滤空白字符: code=$(echo "$code" | tr -d [:space:]) comm=$(echo "$comm" | tr -d [:space:])
  3. 算出字符数: ((code_num += ${#code})) ((comm_num += ${#comm}))

行开头为#的注释行注释字数就简单了:

  1. 过滤空白字符:comm=$(echo "$line" | tr -d [:space:])
  2. 算出字符数:((comm_num += ${#comm}))

大体就这样了,下面是代码,没去验证,因为。。。没时间。

script_count(){
    local code_lines=0 comm_lines=0 code_num=0 comm_num=0
    
    while read line; do
        if echo "$line" | tr -d [:space:] | grep ^[^#]; then    #过滤空白行,且匹配不以#开头的行
            ((code_lines += 1))
            code=${line%%[[:space:]]#*} && code=$(echo "$code" | tr -d [:space:]) && ((code_num += ${#code}))
            if echo "$line" | grep -E *[[:space:]]# ; then     #代码行也会有注释,就像这行
                ((comm_lines += 1))
                comm=${line#*[[:space:]]#} && comm=$(echo "$comm" | tr -d [:space:]) && ((comm_num += ${#comm}))
            fi
        else
            if [ -n "$(echo "$line" | tr -d [:space:])" ]; then
                ((comm_lines += 1))
                comm=$(echo "$line" | tr -d [:space:]) && ((comm_num += ${#comm}))
            fi
        fi
    done < $1
    
    echo $code_lines $comm_lines $code_num $comm_num
}
posted @ 2017-04-20 20:35  carryme15  阅读(215)  评论(0编辑  收藏  举报