统计源代码行数的shell脚本的详细介绍

统计源代码行数的shell脚本的详细介绍

写了一个脚本,可以按模块统计源代码的行数,呵呵。

输出结果:

~ $ ./line-count 
[module]    [lines] [%]
FRED       4744  17.67%
dataset     8591  32.00%
core       9025  33.61%
image       803  2.99%
tape       1339  4.99%
license      16  0.06%
jni       1621  6.04%
util       264  0.98%
test       446  1.66%

total      26849

 

脚本如下:

#!/bin/sh
#
# $Id: line-count,v 1.2 2004/08/06 08:43:16 clkrst Exp $ 
#
# a source-file line counter for C++/C/Java
#
# i use the fixed module list instead of searching all sub-directory,
# because it can give me an exact control.
#
#        clkrst@hotmail.com
#

# count the lines of source files under the given directory
# args: $1 the directory want to check.
#    $2 options
function get_lines () {
  find $1/* $2 | xargs wc -l | tail -1 | cut -b1-7
}

# declare the arrays
declare -a SOURCES   # the directories to check
declare -a NAMES    # the module names
declare -a LINES    # the lines of each module

# the following expresses the line-percentage 
# unit: 0.01
declare -a PERS     # the integer part 
declare -a FRAS     # the fraction part

# here you can add as more SOURCES/NAMES as possible
# the source directory
SOURCES=("src" 
     "src/dataset" 
     "src/core" 
     "src/image" 
     "src/tape" 
     "src/license"
     "jni" 
     "util")
     
# the module name of each directory
NAMES=("FRED"
    "dataset" 
    "core" 
    "image" 
    "tape" 
    "license"
    "jni" 
    "util")

# how many modules?
# should be equal to the sizeof(SOURCES) or sizeof(NAMES)
N_MOD=8

# extra modules
NAMES[$N_MOD]="test"
SOURCES[$N_MOD]="test"
LINES[$N_MOD]=`get_lines ${SOURCES[$N_MOD]} "-maxdepth 2 -name *.cpp -or -name *.h"` ;
N_MOD=$(( $N_MOD+1 ))

# count the lines of each module
L_TOTAL=$(( 0 ))
for (( i=0; $i<$N_MOD; i=$i+1 )) ; do 
  LINES[$i]=`get_lines ${SOURCES[$i]} "-maxdepth 2 -name *.cpp -or -name *.h -or -name *.java"` ; 
  L_TOTAL=$(( $L_TOTAL+${LINES[$i]} )) ; 
done

# calculate the percentage
for (( i=0; $i<$N_MOD; i=$i+1 )) ; do 
  # the formula is:
  #    L_LINES/L_TOTAL * 100 + 0.5 
  # eliminate the float calculation
  #    (L_LINES * 100 + L_TOTAL/2) / L_TOTAL
  # to get fraction part, we use 
  #  fra(X) = (X*100) - (X*100)/100*100
  #  int(X) = (X*100) / 100
  PERS[$i]=$(( (${LINES[$i]}*10000 + $L_TOTAL/2) / $L_TOTAL )) ; 
  FRAS[$i]=$(( ${PERS[$i]} - ${PERS[$i]}/100*100 ));
  PERS[$i]=$(( ${PERS[$i]} / 100 ));
done

# output result
printf "[module]/t[lines]/t[%%]/n"
for (( i=0; $i<$N_MOD; i=$i+1 )) ; 
  do printf "%s/t/t%5d/t%2d.%02d%%/n" ${NAMES[$i]} ${LINES[$i]} ${PERS[$i]} ${FRAS[$i]};
done
printf "/ntotal/t/t%5d/n" $L_TOTAL
  
unset SOURCES NAMES LINES PERS
unset N_MOD L_TOTAL