bashのコードの行数(空白ではない)を数える


151

Bashで、プロジェクト内の空白でないコード行の数を数えるにはどうすればよいですか?


1
以下のソリューションの多くは、1つのファイル(例:)に対してのみ機能しますfoo.c。プロジェクトの合計行数(たとえば、ディレクトリ構造内の多くのファイル、バイナリファイルを除く)について何か考えはありますか?
solvepuzzles 2012

5
@solvingPuzzles私はその部分に答えることができると思います。「cat FILE | sed blah」などの1つのファイルで機能するソリューションの場合、「find。-name '*」のように、「cat FILE」を、操作するファイル名をリストするコマンドに置き換えることで、多くのファイルを処理できます。 .py '"、そしてそれを" xargs cat "にパイプします。例 "find。-name '* .py' | xargs cat | sed '/ ^ \ s * $ / d' | wc -l"
Jonathan Hartley

2
@JonathanHartley @solvingPuzzlesなどのプログラムもslocありcloc、コード行のカウントを行うためにここにあります。
AsTeR 2015

OPここ:最初にこの問題を尋ねたとき、 'cloc'はPythonコードに対してあまりうまく機能しませんでした。今日、それは素晴らしいです。
Jonathan Hartley

clocはnpmモジュールとしても利用でき、時間を大幅に節約できます。
クリシュナヴェドゥラ2017年

回答:


193
cat foo.c | sed '/^\s*$/d' | wc -l

また、コメントの空白行を検討する場合:

cat foo.pl | sed '/^\s*#/d;/^\s*$/d' | wc -l

ただし、それは言語に依存します。


24
なぜ猫を使っているのかわからない。sedに渡すファイル名としてfoo.cまたはfoo.plを使用します。sed '/ ^ \ s * $ / d' foo.c | wc -l
アンディレスター

28
ただ習慣。パイプラインを左から右に読み取ります。つまり、通常は猫から始め、次にアクション、アクション、アクションなどを行います。明らかに、最終結果は同じです。
マイケルクレイマー

32
すべてのサブフォルダーのすべてのファイルに対してこれを行い、 '//'でコメントを除外するには、このコマンドを次のように拡張します:find。-type f -name '* .c' -exec cat {} \; | sed '/ ^ \ s *#/ d; / ^ \ s * $ / d; / ^ \ s * \ / \ // d' | wc -l
ベンジャミンインタル

11
UUOC:なしで左から右に読むことができます< foo.pl sed 'stuff' | wc -l
jw013

22
一般的に言えば、UUOCは重要ではありませんが、読みやすさが重要です。
アンデルサンド

52
#!/bin/bash
find . -path './pma' -prune -o -path './blog' -prune -o -path './punbb' -prune -o -path './js/3rdparty' -prune -o -print | egrep '\.php|\.as|\.sql|\.css|\.js' | grep -v '\.svn' | xargs cat | sed '/^\s*$/d' | wc -l

上記は、プロジェクト(現在のフォルダーとすべてのサブフォルダーを再帰的に)のコード行の合計数(空白行は削除されます)を示します。

上記の「./blog」「./punbb」「./js/3rdparty」と「./pma」は、コードを記述しなかったため、ブラックリストに登録したフォルダーです。また、.php、.as、.sql、.css、.jsは、表示されるファイルの拡張子です。拡張子が異なるファイルは無視されます。


1
Railsアプリのバリエーション:find。-path './log' -prune -o -path './trunk' -prune -o -path './branches' -prune -o -path './vendor' -prune -o -path './tmp '-prune -o -print | egrep '\ .rb | \ .erb | \ .css | \ .js | \ .yml' | grep -v 'svn' | xargs猫| sed '/ ^ \ s * $ / d' | wc -l
ポーズID 2012年

1
a $をgrep(...\.js$|...)に追加する必要がありfeature.js.swpます。そうしないと一致します。
Xeoncross

アンカーを忘れたため、間違ったファイルが含まれています。アンカー付きのさらにシンプルなバージョン:find . | egrep '.\.c$|.\.h$' | xargs cat | sed '/^\s*$/d' | wc -l
マークジェロニムス

36

シェルスクリプト以外のものを使用する場合は、CLOCを試してください

clocは、多くのプログラミング言語のソースコードの空白行、コメント行、および物理行をカウントします。これは完全にPerlで記述されており、Perl v5.6以降の標準ディストリビューション(一部の外部モジュールからのコードはcloc内に埋め込まれています)の外部に依存していません。


2
私が最初にこの質問をしたとき、 'cloc'はPython docstringをコード行として数えました。これは次善のIMHOでした。'cloc'の最新バージョンは、Python docstringをコメントとして数えるようになりました。
Jonathan Hartley

これが正解です。私はちょうどclocを試してみました、そしてそれはうまくいきます。
LeeMobile

31

これを行うには、一般的なシェルユーティリティを使用して多くの方法があります。

私の解決策は:

grep -cve '^\s*$' <file>

これは、<file>内の行を検索します。一致しない(-v)行は、パターン(-e) '^ \ s * $'と一致します。行の終わりまで(つまり、空白以外のコンテンツがない場合)、一致する行自体ではなく、一致する行の数(-c)を表示します。

へのパイプを含むメソッドに対するこのメソッドの利点は、wc複数のファイルを指定して、ファイルごとに個別のカウントを取得できることです。

$ grep -cve '^\s*$' *.hh

config.hh:36
exceptions.hh:48
layer.hh:52
main.hh:39

2
ありがとう!ちなみに、wcは、指定された各ファイルの数と合計を提供します。
ジョナサンハートレー

1
ただし、標準で数えると、1つのファイルとしてカウントされます。
SpoonMeiser 2009年

これは私の意見では最良の答えです。
simhumileco 2018

-e必要ありません。これがパターンの通常の位置であり、ファンキーなことは何もしていません。しかし、それがあなたのスタイルであれば、明示的であることには何の問題もありません。
Jacktose

13

'wc'は行、単語、文字を数えるので、すべての行(空白の行を含む)を数えるには、次のようにします。

wc *.py

空白行を除外するには、grepを使用できます。

grep -v '^\s*$' *.py | wc

'-v'はgrepに、 '^'に一致する行を除くすべての行を出力するように指示します '\ s *'はゼロ以上の空白文字 '$'は行の終わり* .pyは私の例ですカウントするすべてのファイル(現在のディレクトリ内のすべてのpythonファイル)は、出力をwcにパイプします。やめろ

私は自分の(本物の)質問に答えています。これをカバーするスタックオーバーフローエントリが見つかりませんでした。


5
\ Wは空白との一致ではなく、単語以外の文字と一致します。単語文字\ wの反対です。\ W英数字でもアンダースコアでもないものに一致するため、ここでの主張どおりに動作しません。あなたは\ sを意味します
SpoonMeiser 2008

9

このコマンドは、空白でない行の数をカウントします。
cat fileName | grep -v ^$ | wc -l
grep -v ^ $正規表現関数は空白行を無視します。


この答えは最も簡単です
samthebest 2018年

2
catこのチェーンでは必要ありませんgrep -v ^$ fileName | wl -l
。–エタリド

7
必要もありませんwc -lグレップが持っているためには、-cgrep -vc ^$ fileName
Jacktose


5
cat 'filename' | grep '[^ ]' | wc -l

トリックはうまくいくはずです


3
最初にファイル名を引数としてgrepに渡すことができるのに、なぜcatを使用してファイルをgrepにパイプするのですか?
SpoonMeiser 2008


4
awk '/^[[:space:]]*$/ {++x} END {print x}' "$testfile"

1
文字通りawkスクリプトでプリインクリメントを使用するのを見たことがないので、私はこれに賛成票を投じますが、残念ながら、これは空白行のみを数えます。:)意味しawk '!/^[[:space:]]*$/{++x} END{print x}'ます。または、ネガが本当に嫌いなら、awk '{y++} /^[[:space:]]*$/{++x} END{print y-x}';)
dannysauer 2013

4
grep -cvE '(^\s*[/*])|(^\s*$)' foo

-c = count
-v = exclude
-E = extended regex
'(comment lines) OR (empty lines)'
where
^    = beginning of the line
\s   = whitespace
*    = any number of previous characters or none
[/*] = either / or *
|    = OR
$    = end of the line

他のオプションが私に間違った答えを与えたので、私はこれを投稿します。これは、コメント行が/または*で始まる私のJavaソースで機能しました(私は複数行コメントのすべての行で*を使用しています)。


これは実行可能なソリューションです。唯一の注意点:複数行のコメントはカウントされません
Amol

2

以下は、プロジェクトのコード行をカウントするBashスクリプトです。ソースツリーを再帰的に走査し、空白行と「//」を使用する単一行コメントを除外します。

# $excluded is a regex for paths to exclude from line counting
excluded="spec\|node_modules\|README\|lib\|docs\|csv\|XLS\|json\|png"

countLines(){
  # $total is the total lines of code counted
  total=0
  # -mindepth exclues the current directory (".")
  for file in `find . -mindepth 1 -name "*.*" |grep -v "$excluded"`; do
    # First sed: only count lines of code that are not commented with //
    # Second sed: don't count blank lines
    # $numLines is the lines of code
    numLines=`cat $file | sed '/\/\//d' | sed '/^\s*$/d' | wc -l`

    # To exclude only blank lines and count comment lines, uncomment this:
    #numLines=`cat $file | sed '/^\s*$/d' | wc -l`

    total=$(($total + $numLines))
    echo "  " $numLines $file
  done
  echo "  " $total in total
}

echo Source code files:
countLines
echo Unit tests:
cd spec
countLines

これが私のプロジェクトの出力です

Source code files:
   2 ./buildDocs.sh
   24 ./countLines.sh
   15 ./css/dashboard.css
   53 ./data/un_population/provenance/preprocess.js
   19 ./index.html
   5 ./server/server.js
   2 ./server/startServer.sh
   24 ./SpecRunner.html
   34 ./src/computeLayout.js
   60 ./src/configDiff.js
   18 ./src/dashboardMirror.js
   37 ./src/dashboardScaffold.js
   14 ./src/data.js
   68 ./src/dummyVis.js
   27 ./src/layout.js
   28 ./src/links.js
   5 ./src/main.js
   52 ./src/processActions.js
   86 ./src/timeline.js
   73 ./src/udc.js
   18 ./src/wire.js
   664 in total
Unit tests:
   230 ./ComputeLayoutSpec.js
   134 ./ConfigDiffSpec.js
   134 ./ProcessActionsSpec.js
   84 ./UDCSpec.js
   149 ./WireSpec.js
   731 in total

楽しい!- カラン


1

プロジェクトにあるファイルの数に依存します。理論的には、

grep -c '.' <list of files>

検索ユーティリティを使用してファイルのリストを入力できる場所。

grep -c '.' `find -type f`

ファイルごとの行数が表示されます。


1
。空白と一致します。このソリューションが機能するのは、空白のみを含む行を空白でないと見なした場合のみです。
SpoonMeiser 2008

1

現在のディレクトリ内の特定のファイル拡張子を持つ空白以外のすべての行を再帰的にカウントするスクリプト:

#!/usr/bin/env bash
(
echo 0;
for ext in "$@"; do
    for i in $(find . -name "*$ext"); do
        sed '/^\s*$/d' $i | wc -l ## skip blank lines
        #cat $i | wc -l; ## count all lines
        echo +;
    done
done
echo p q;
) | dc;

使用例:

./countlines.sh .py .java .html

レシピの「空白ではない」部分については、@ Andy Lester(コメントへの+1)に感謝します。
キース・ピンソン

@Michael Cramer(あなたの投稿に+1)も(少し冗長な)「空白でない」ソリューションを最初に投稿してくれたことに感謝します。
キース・ピンソン、2011

1

プロジェクト全体で、特定のファイル拡張子のすべてのファイルのすべての非空白行の合計が必要な場合:

while read line
do grep -cve '^\s*$' "$line"
done <  <(find $1 -name "*.$2" -print) | awk '{s+=$1} END {print s}'

最初の引数はプロジェクトのベースディレクトリ、2番目はファイル拡張子です。使用例:

./scriptname ~/Dropbox/project/src java

これは、以前のソリューションのコレクションに過ぎません。


これは、各ファイルで1行に1回grepを起動することで、fork + exec呼び出しの最大数の賞を獲得します。;)
dannysauer 2013

0
grep -v '^\W*$' `find -type f` | grep -c '.' > /path/to/lineCountFile.txt

現在のディレクトリとそのサブディレクトリにあるすべてのファイルの合計数を示します。

HTH!


\ Wは単語以外の文字です。これは${-[*]} + $@、たとえばのような行とは一致しません。これは確かに世界のどこかで有効なコードです。;)スペースの\ sを意味します。
dannysauer 2013

0

これは空白行を数えずに行数を数えます:

grep -v ^$ filename wc -l | sed -e 's/ //g' 


-3

Linuxにはこのための「wc」というプログラムがすでにあります。

ただ

wc -l *.c 

そして、それはあなたに合計行と各ファイルの行を与えます。


3
ねえ。「wc」自体はサブディレクトリを検索せず、空白行を除外しません。どちらも質問で明示的に要求されました。
ジョナサンハートレー

wc空白行を数えます。OPは空白以外の行を数えたいと考えています。彼が使いたいのは本当ですがwc、それを使用してストリーム編集された後でなければsed
EhevuTov
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.