読者です 読者をやめる 読者になる 読者になる

試される大地から

furaiboが送る技術ブログ。プログラミングのTipsなど書いていきます。

ファイル全体の行数を表示するシェルスクリプト

ファイル全体の行数を表示するスクリプトが欲しいと思い、練習がてら作った。


#!/bin/sh
#
# ソフトウェアの総行数を取得するシェルスクリプト
#

# 変数
# 各自必要に応じて改変のこと
dir="./"			# ファイルのあるディレクトリを指定する
ext=("py" "js" "html")		# 拡張子指定(ピリオド抜き)
nlarray=()			# 拡張子ごとの行数を格納する配列
sum=0				# 総行数を表す変数



# 配列の初期化
count=0
for i in ${ext[@]}
do
	nlarray[$count]=0
	count=$(($count+1))
done


# ファイルの検索
count=0
for i in ${ext[@]}
do
	for j in `find $dir -name "*.$i"`
	do
		# AWKを使って行数を取得
		tmp=`awk 'END{print NR}' $j`
		sum=$((sum+tmp))
		
		# 拡張子ごとにファイルの総行数を計算
		# 正規表現
		if [[ $j =~ $i ]]
		then
			nlarray[$count]=$((${nlarray[$count]} + $tmp))
		fi
	done
	count=$(($count+1))
done


# 総行数を表示
echo "起点 : ${dir}"
echo "総行数 : ${sum}"


# 内訳を表示
count=0
echo "<内訳>"
for i in ${ext[@]}
do
	echo "$i : ${nlarray[$count]}"
	count=$(($count+1))
done


実行結果は以下の通り。

[furaibo@localhost デスクトップ]$ ./numoflines.sh
起点 : ./scalrmodoki_server
総行数 : 1696
<内訳>
py : 1646
js : 0
html : 50



なんだか、すごく不恰好なスクリプトになってしまった。変数countが何度も現れるのでスマートではない。これには理由があって、当初書いたスクリプトが思ったように動かなかったためだ。


#!/bin/sh
#
# ソフトウェアの総行数を取得するシェルスクリプト
#

# 変数
# 各自必要に応じて改変のこと
dir="./"			# ファイルのあるディレクトリを指定する
ext=("py" "js" "html")		# 拡張子指定(ピリオド抜き)
nlarray=()			# 拡張子ごとの行数を格納する配列
sum=0				# 総行数を表す変数

# 配列の初期化
for i in ${ext[@]}
do
	nlarray["$i"]=0
done

# ファイルの検索
for i in ${ext[@]}
do
	for j in `find $dir -name "*.$i"`
	do
		echo $i

		# AWKを使って行数を取得
		tmp=`awk 'END{print NR}' $j`
		sum=$((sum+tmp))
		
		# 拡張子ごとにファイルの総行数を計算
		# 正規表現
		if [[ $j =~ $i ]]
		then
			echo $j
			nlarray["$i"]=`expr ${nlarray[$i]} + $tmp`
		fi
	done
done

# 総行数を表示
echo "起点 : ${dir}"
echo "総行数 : ${sum}"

# 内訳を表示
for i in ${ext[@]}
do
	echo "$i : ${nlarray[$i]}"
done



これで正しく動くつもりだったのだが、

nlarray["$i"]=`expr ${nlarray[$i]} + $tmp`

の部分で意図しない動作が起き、思い通りの結果が得られなかった。
2番目のスクリプトを実行すると、


[furaibo@localhost デスクトップ]$ ./numoflines.sh
起点 : ./scalrmodoki_server
総行数 : 1696
<内訳>
py : 1696
js : 1696
html : 1696


となってしまい、どうしても治らなかった。どうも連想配列でexprや$(())といった形式で加算を行おうとすると連想配列全体の要素に加算が行われてしまうようだ。これはbashのバグか、あるいは仕様であるかは今のところ不明である。