ディレクトリ内のすべてのコード行を再帰的にカウントする方法は?


1624

PHPアプリケーションがあり、特定のディレクトリとそのサブディレクトリの下にあるすべてのコード行をカウントしたいと考えています。大まかなアイデアを得ようとしているだけなので、コメントを無視する必要はありません。

wc -l *.php 

このコマンドは、特定のディレクトリ内で適切に機能しますが、サブディレクトリを無視します。私はこれはうまくいくかもしれないと思っていましたが、それは74を返しています、それは間違いなくそうです...

find . -name '*.php' | wc -l

すべてのファイルをフィードするための正しい構文は何ですか?

回答:


2650

試してください:

find . -name '*.php' | xargs wc -l

SLOCCountツールも役立ちます。

それはあなたがそれを指しているどんな階層のためのコードカウントの正確なソース行といくつかの追加の統計を与えます。

ソートされた出力:

find . -name '*.php' | xargs wc -l | sort -nr


31
cloc.sourceforge.netは、sloccount(より多くの言語でより少ない情報)の代替として一見の価値があるかもしれません
AsTeR

31
インクルードファイルも:find . -name '*.php' -o -name '*.inc' | xargs wc -l
rymo

52
これは、多くのファイルが(存在する場合に複数の番号が印刷されますwc。複数回実行されます。また、多くの特殊ファイル名を処理しません
l0b0

42
@idober:find . -name "*.php" -not -path "./tests*" | xargs wc -l
エンドレ

19
ディレクトリ名にスペースが含まれている場合...上記のコマンドは失敗します!!
nitish712 2014年

474

別のワンライナーの場合:

( find ./ -name '*.php' -print0 | xargs -0 cat ) | wc -l

スペースを含む名前で機能し、1つの数値のみを出力します。


1
+1 ditto ...永遠に検索...他のすべての「find」コマンドは実際のファイルの数のみを返しました....ここで-print0のものは実際の行数を取得しました!!! ありがとう!
ロネドッグ

3
@ TorbenGundtofte-Bruun- man find..を参照してください。xargs- 0を指定したprint0を使用すると、名前にスペースまたはその他の奇妙な文字が含まれるファイルを操作できます
Shizzmo

2
@ TorbenGundtofte-Bruun-また、xargsの-0はprint0に対応します。これは、スペースを処理するための一種のエンコード/デコードです。
Tristan Reid 2014

7
:あなたは複数の名前のフィルタが必要な場合は、私は(少なくとも、検索のMSYSGitバージョンで)、あなたは余分な括弧必要があることを発見しました ( find . \( -name '*.h' -o -name '*.cpp' \) -print0 | xargs -0 cat ) | wc -l
Zrax

1
@DesignbyAdrian:ジャーナリングは、速度ではなくクラッシュの回復に役立ちます。キャッシュまたは非常に高速なHDDにより、パフォーマンスが向上している可能性があります。
jmh

398

最近のバージョンのBash(またはZSH)を使用している場合は、はるかに簡単です。

wc -l **/*.php

Bashシェルでは、このglobstarオプションを設定する必要があります。それ以外の場合、**glob-operatorは再帰的ではありません。この設定を有効にするには、

shopt -s globstar

これは永続的なものにするには、初期化ファイルの1(に追加~/.bashrc~/.bash_profileなど)。


7
簡単にするためにこれを賛成していますが、ディレクトリを再帰的に検索しているようには見えず、現在のディレクトリのサブディレクトリのみをチェックすることを指摘しておきます。これはSL6.3にあります。
Godric Seer 2013

7
これは、シェルと設定したオプションによって異なります。これを機能globstarさせるに Bash を設定する必要があります
Michael Wild

2
@PeterSenna、現在の3.9.8カーネルアーカイブでは、コマンドwc -l **/*.[ch]は合計15195373行を検出します。それが「非常に低い値」であると考えるかどうかわかりません。ここでも、globstarBashで有効になっていることを確認する必要があります。で確認できshopt globstarます。明示的に有効にするには、を実行しますshopt -s globstar
マイケルワイルド

5
@MichaelWildこれは良い解決策ですが、が組み込まれていないため、ARG_MAX多数の.phpファイルがある場合でもオーバーフローしますwc
モニカを復活させてください

1
@AlbertSamuelいいえ、両方の方法で作成されたファイルのリストを比較する必要があります。私の方法には、@ BroSlowで言及されているように、多数のファイルに対して機能しないという問題があります。によって生成されたパスにfindスペースが含まれている場合、受け入れられた回答は失敗します。これは、それぞれとを使用print0--nullて修正することができます。findxargs
マイケルワイルド

363

clocこの目的のために作成されたユーティリティを使用できます。各言語の行数とコメント数をレポートします。CLOCはLinux、Mac、Windowsで利用できます。

使用法と出力例:

$ cloc --exclude-lang=DTD,Lua,make,Python .
    2570 text files.
    2200 unique files.                                          
    8654 files ignored.

http://cloc.sourceforge.net v 1.53  T=8.0 s (202.4 files/s, 99198.6 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Javascript                    1506          77848         212000         366495
CSS                             56           9671          20147          87695
HTML                            51           1409            151           7480
XML                              6           3088           1383           6222
-------------------------------------------------------------------------------
SUM:                          1619          92016         233681         467892
-------------------------------------------------------------------------------

4
それは素晴らしいツールで、最後に便利な統計をすばやく提供します。大好きです。
Rob Forrest

4
cygwin(または他の同様のポート/環境)を使用して、WindowsでUnixコマンドを実行できることに注意してください。私にとって、この種のアクセスが非常に便利であることは、必要不可欠です。UNIXコマンドラインは魔法です。私は特にperlと正規表現が好きです。
Curtis Yallop、2014年

CLOCとSLOCCountは2015年半ばのMacbookで正常に動作します。それらの数は近いですが、127k Java Androidプロジェクトでは正確に同じではないことに注意してください。また、iOS版のLoCは2倍でした。そのため、SLOCCountの「コスト」メトリックがオフになる可能性があります(またはiOS開発者がAndroid開発者が作成したものの2倍になる可能性があります。:-)
maxweber

2
これclocは単なるPerlスクリプトなので、この質問の冒頭を編集して、クロスプラットフォームであることを明確にしてみませんか?
カイルストランド

もちろん、Windows bashでも問題なく動作します。
yurisnm

100

UNIXライクなシステムには、clocコード統計を提供するというツールがあります。

私はそれが言う私たちのコードベースのランダムなディレクトリに出くわしました:

      59 text files.
      56 unique files.                              
       5 files ignored.

http://cloc.sourceforge.net v 1.53  T=0.5 s (108.0 files/s, 50180.0 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C                               36           3060           1431          16359
C/C++ Header                    16            689            393           3032
make                             1             17              9             54
Teamcenter def                   1             10              0             36
-------------------------------------------------------------------------------
SUM:                            54           3776           1833          19481
-------------------------------------------------------------------------------

2
@moose技術的にはsimtaoは、Windowsユーザー向けのソリューションとして具体的に言及しており、linuxやunixについてはまったく触れていません。
Tim Seguine、2015年

5
@moose Tableは私の回答よりもはるかに遅れて彼の回答に編集されましたが、2つは実際に似ています。
カルマリウス2015年

私はそれが好きです。clocは本当にきれいです。しかし、その名前はどういう意味ですか?
Manoel Vilela 2017

それは今でもWindowsにあります!あなたがチョコレートを持っていると仮定します:choco install cloc
icc97

35

そこにファイルがいくつあるか、または何が望ましい出力であるかを指定しませんでした。これはあなたが探しているものですか?

find . -name '*.php' | xargs wc -l

2
これは、ファイルが多すぎない限り機能します。多くのファイルがある場合、結果として数行が表示されます(xargsはファイルリストをいくつかのサブリストに分割します)
Pascal MARTIN

ああ、そうです。だから私は彼がそこにいくつのファイルがあるかを指定しなかったと私が言った理由です。私のバージョンは覚えやすいですが、Shinのバージョンは、ファイルがいくつかある場合に適しています。私はそれを投票しています。
パヴェルPolewicz

:私は、単一引用符があまりにも制限されている機能で使用するためにこれを適応させるために必要な go () { mkdir /tmp/go; [[ -f ./"$1" ]] && mv ./"$1" /tmp/go; (find ./ -type f -name "$*" -print0 | xargs -0 cat ) | wc -l; wc -l /tmp/go/*; mv /tmp/go/* . } 結果が近いためslocountでした*.pyが、それは知りませんでした*.js*.html
jalanb

31

さらに別のバリエーション:)

$ find . -name '*.php' | xargs cat | wc -l

編集:ファイルごとではなく、合計が表示されます。

Edit2:後で追加.findて機能させる


両方の答えは行を合計します。
josh123a123 14

:少なくともcygwinの中で、私はとのより良い結果を持っていた$ find -name \*\.php -print0 | xargs -0 cat | wc -l
マーティンHaeberliが

ダーウィンでは、これは総計find . -name '*.php' | xargs cat | wc -lを提供します:...これはファイルfind . -name '*.php' | xargs wc -l
ごとの

30

驚いたことに、find -execとに基づく回答はありませんawk。さあ行こう:

find . -type f -exec wc -l {} \; | awk '{ SUM += $0} END { print SUM }'

このスニペットは、すべてのファイルを検索します(-type f)。ファイル拡張子で検索するには、次を使用します-name

find . -name '*.py' -exec wc -l '{}' \; | awk '{ SUM += $0; } END { print SUM; }'

2
機能的にはこれは完全に機能しますが、大規模なリスト(Linuxソース)では、すべてのファイルに対して1つのwcプロセスではなく、各ファイルに対してwcプロセスを開始するため、非常に遅くなります。この方法では31秒で計測しましたが、では1.5秒で計測しましたfind . -name '*.c' -print0 |xargs -0 wc -l。とは言うものの、このより高速な方法(少なくともOS Xでは)は「合計」を数回出力するため、適切な合計を取得するには追加のフィルタリングが必要です(詳細は回答に投稿しました)。
Doug Richardson

これには、無制限の数のファイルを処理できるという利点があります。よくやった!
ekscrypto 2016年

1
これは、大量のGBとファイルを処理した後のはるかに優れたソリューションです。wcaの形式で1つを実行するcatと、システムが最初にすべてのGBを処理して行のカウントを開始する必要があるため、遅いです(200GBのjson、12kファイルでテスト)。wc最初に実行してから結果をカウントする方がはるかに高速です
ulkas 2018年

1
@DougRichardson、代わりにこれを検討することもできます。find . -type f -exec wc -l {} \+または find . -name '*.py' -type f -exec wc -l {} \+ 、出力の最後に合計を出力します。興味があるのが合計だけの場合は、少し先に進んで使用することもできますtailfind . -type f -exec wc -l {} \+ | tail -1またはfind . -name '*.py' -type f -exec wc -l {} \+ | tail -1
JamieJag

25

私の場合より一般的で単純ですが、異なる名前拡張子のファイルを数える必要があるとしましょう(たとえば、ネイティブも)

wc $(find . -type f | egrep "\.(h|c|cpp|php|cc)" )

フィードバックをありがとう、私はそれを修正しました。


6
これはあなたの考えていることをまったくしません。見つける -name ' 。[am]'は find と同じです。-name '。[a | m]'両方とも、.mまたは.aで終わるすべてのファイルを検索します
Omry Yadan

1
しかし、2番目は。で終わるファイルも検索します。| 、もしあれば。したがって、[h | c | cpp | php | cc]は[hcp |]と同じになります。
OsamaBinLogin 2016年

バックティックは非推奨です。優先$()
Sandburg

これはCygwinで動作します。もちろん、「C:\」ドライブは、たとえば次のようにcygwin規則に従う必要があります。wc $(find / cygdrive / c // SomeWindowsFolderj / -type f | egrep "\。(h | c | cpp | php | cc) ")
Christian Gingras

21

POSIX

ここでの他のほとんどの回答とは異なり、これらは任意のPOSIXシステム、任意の数のファイル、任意のファイル名(注記がある場合を除く)で機能します。


各ファイルの行:

find . -name '*.php' -type f -exec wc -l {} \;
# faster, but includes total at end if there are multiple files
find . -name '*.php' -type f -exec wc -l {} +

各ファイルの行、ファイルパスでソート

find . -name '*.php' -type f | sort | xargs -L1 wc -l
# for files with spaces or newlines, use the non-standard sort -z
find . -name '*.php' -type f -print0 | sort -z | xargs -0 -L1 wc -l

各ファイルの行、行数でソート、降順

find . -name '*.php' -type f -exec wc -l {} \; | sort -nr
# faster, but includes total at end if there are multiple files
find . -name '*.php' -type f -exec wc -l {} + | sort -nr

すべてのファイルの合計行

find . -name '*.php' -type f -exec cat {} + | wc -l

19

ディレクトリ内のコード行をカウントするsloccountと呼ばれる小さなツールがあります。空の行/コメントを無視し、プログラミング言語ごとに結果をグループ化し、いくつかの統計を計算するため、必要以上のことを行うことに注意してください。


Windowsの場合、LocMetricsが仕事をします
Camille

15

あなたが欲しいのは単純なforループです:

total_count=0
for file in $(find . -name *.php -print)
do
    count=$(wc -l $file)
    let total_count+=count
done
echo "$total_count"

3
これが示唆する答えと比較して、このやり過ぎではありませんxargsか?
Nathan Fellman

5
いいえ、ネイサン。xargsの回答は、必ずしもカウントを1つの数値として出力するわけではありません。小計をたくさん印刷するだけかもしれません。
ロブ・ケネディ

3
ファイル名にスペースが含まれている場合、このプログラムは何をしますか?改行はどうですか?;-)
パヴェルPolewicz

38
ファイル名に新しい行が含まれている場合、より大きな問題があると思います。
Kzqai 2012

2
@ennuikillerこれに関する問題の数。最初に、空白のあるファイルで壊れます。IFS=$'\n'ループの前に設定すると、名前に改行が含まれるファイルを除いて、少なくともそれを修正します。第二に、あなたはクォート'*.php'ではないので、シェルでは展開されずに展開されますfind、そしてエルゴは実際にはサブディレクトリでphpファイルを見つけません。また、-print他のアクションがない場合に暗黙的に指定されるため、これは冗長です。
モニカを復活させてください

12

ソースのみ:

wc `find`

フィルタリングするには、grepを使用します

wc `find | grep .php$`

11

高速で、findファイルの数が多すぎる(数値引数がオーバーフローしている)場合でも失敗せず、のすべての検索/フィルタリング機能を使用しxargs、名前に変な記号が含まれているファイルを正常に処理し、を使用しないと、外部コマンド(に感謝の無駄に高い数+のためfind-exec)。どうぞ:

find . -name '*.php' -type f -exec cat -- {} + | wc -l

2
私は(とその変種自分自身を投稿することについてでした\;代わりに+、私はそれに気づいていなかったとして)、この答えが正解でなければなりません。
Mark K Cowan

7

質問にタグが付けられていることを知っています 、しかしあなたが解決しようとしている問題はPHP関連でもあるようです。

Sebastian Bergmannは、PHPLOCと呼ばれるツールを作成しました。これは、あなたがやりたいことを実行し、その上に、プロジェクトの複雑さの概要を提供します。これはそのレポートの例です:

Size
  Lines of Code (LOC)                            29047
  Comment Lines of Code (CLOC)                   14022 (48.27%)
  Non-Comment Lines of Code (NCLOC)              15025 (51.73%)
  Logical Lines of Code (LLOC)                    3484 (11.99%)
    Classes                                       3314 (95.12%)
      Average Class Length                          29
      Average Method Length                          4
    Functions                                      153 (4.39%)
      Average Function Length                        1
    Not in classes or functions                     17 (0.49%)

Complexity
  Cyclomatic Complexity / LLOC                    0.51
  Cyclomatic Complexity / Number of Methods       3.37

ご覧のように、提供される情報は、プロジェクトの作業を開始する前に、プロジェクトの複雑さを大まかに把握できるため、開発者の観点から見るとはるかに役立ちます。


7

誰もこれが奥に埋もれているのを見ることはないと思います...しかし、これまでのところ、ファイル名にスペースが含まれているという問題については、答えはありません。さらに、xargsツリー内のパスの全長がシェル環境のサイズ制限(Linuxではデフォルトで数メガバイト)を超えると、すべての使用が失敗する可能性があります。これらはかなり直接的な方法でこれらの問題を修正するものです。サブシェルはスペースを含むファイルを処理します。awk個々のファイルwc出力のストリームの合計なので、スペースが不足することはありません。また、execファイルのみに制限します(ディレクトリをスキップします)。

find . -type f -name '*.php' -exec bash -c 'wc -l "$0"' {} \; | awk '{s+=$1} END {print s}' 

6

WC -L?GREP -Cを使用することをお勧めします^

wc -l?違う! wcコマンドは、行ではなく新しい行コードをカウントします!ファイルの最後の行が新しい行コードで終わっていない場合、これはカウントされません!

それでもcount行が必要な場合は、grep -c ^を使用します 。完全な例:

#this example prints line count for all found files
total=0
find /path -type f -name "*.php" | while read FILE; do
     #you see use grep instead wc ! for properly counting
     count=$(grep -c ^ < "$FILE")
     echo "$FILE has $count lines"
     let total=total+count #in bash, you can convert this for another shell
done
echo TOTAL LINES COUNTED:  $total

最後に、wc -lトラップに注意してください (カウントではなく、行に入ります!!!)


行のPOSIX定義を読んでください。ではgrep -c ^不完全な行の数を数えているので、そのような不完全な行はテキストファイルに表示できません。
gniourf_gniourf 2015

2
私はそれを知っている。EOLがないため、実際には最後の行だけが不完全になる可能性があります。アイデアは、不完全な行を含むすべての行を数えています。これは非常によくある間違いで、完全な行だけを数えます。数えた後、「なぜ最後の行を逃したのですか???」と思っています。これが答えの理由であり、レシピを正しく実行する方法です。
Znik 2015

または、1つのライナーが必要な場合:find -type f -name '*.php' -print0 | xargs -0 grep -ch ^ | paste -sd+ - | bc 代替手段については、こちらを参照してくださいbcstackoverflow.com/q/926069/2400328
techniao

4

非常に簡単に

find /path -type f -name "*.php" | while read FILE
do
    count=$(wc -l < $FILE)
    echo "$FILE has $count lines"
done

1
いずれか1つのファイル名にスペースや改行がある場合、それは失敗します
パヴェルPolewicz

4

結果を行数でソートしたい場合は、次のように最初の回答に| sortor | sort -r-r降順)を追加します。

find . -name '*.php' | xargs wc -l | sort -r

1
の出力xargs wc -lは数値なので、実際にはsort -nor を使用する必要がありますsort -nr
ダスティンイングラム

4

以下のためのWindows、簡単かつ迅速なツールですLocMetrics


彼らがbashを使用している場合、OPがWindows上に存在することはほとんどありません。

1
@VanessaMcHaleの質問のタイトルと説明の両方で、UNIXのみのソリューションが明確に必要なわけではありません。したがって、Windowsベースのソリューションは許容可能です。また、同様の解決策を探していたときに、Googleからこのページが表示されました。
walv 2018年

このコメントは私を助けました。私はこれを試しました、そしてそれはうまくいきます。
アランF

4

何か違います:

wc -l `tree -if --noreport | grep -e'\.php$'`

これは罰金を動作しますが、あなたは、少なくとも一つ持っている必要があり*.php、現在のフォルダ内のファイルやサブフォルダの1、または他のwc屋台を


ARG_MAXもオーバーフローする可能性があります
Mark K Cowan

4

Linuxを使用している場合は(私もそうです)、私のツールpolyglotをお勧めします。sloccountまたはよりも劇的に高速で、clocより機能的ですsloccount

あなたはそれを呼び出すことができます

poly .

または

poly

そのため、複雑なbashスクリプトよりもはるかにユーザーフレンドリーです。


4

zsh globsを使用すると非常に簡単です。

wc -l ./**/*.php

bashを使用している場合は、アップグレードするだけです。bashを使用する理由はまったくありません。


4

ツールTokeiは、ディレクトリ内のコードに関する統計を表示します。Tokeiは、ファイル数、ファイル内の合計行数、コード、コメント、および空白を言語別にグループ化して表示します。トケイは、Mac、Linux、Windowsでもご利用いただけます。

Tokeiの出力の例は次のとおりです。

$ tokei
-------------------------------------------------------------------------------
 Language            Files        Lines         Code     Comments       Blanks
-------------------------------------------------------------------------------
 CSS                     2           12           12            0            0
 JavaScript              1          435          404            0           31
 JSON                    3          178          178            0            0
 Markdown                1            9            9            0            0
 Rust                   10          408          259           84           65
 TOML                    3           69           41           17           11
 YAML                    1           30           25            0            5
-------------------------------------------------------------------------------
 Total                  21         1141          928          101          112
-------------------------------------------------------------------------------

リポジトリ内のREADMEファイルの指示に従って Tokeiをインストールできます


1
これは受け入れられる答えになるはずです
Elijas

3

GnuWin32がインストールされていれば、Windowsでも非常に単純な1行のコマンドを使用できます。このような:

cat `/gnuwin32/bin/find.exe . -name *.php` | wc -l

find.exeの場所を正確に指定する必要があります。指定しない場合、Windowsが提供するFIND.EXE(古いDOSのようなコマンドから)が実行されます。これは、環境PATHのGnuWin32の前であり、パラメーターと結果が異なるためです。

上記のコマンドでは、単一引用符ではなく逆引用符を使用する必要があることに注意してください。


上記の例では、cmd.exeの代わりにWindowsのbashを使用しています。そのため、バックスラッシュ「\」ではなく、スラッシュ「/」を使用しています。
Neven Boyanov

3

最も長いファイルを最初に与え(つまり、これらの長いファイルにはリファクタリングの愛が必要かもしれません)、ベンダーのディレクトリを除外します。

 find . -name '*.php' | xargs wc -l | sort -nr | egrep -v "libs|tmp|tests|vendor" | less

3

シンプルにしたい場合は、仲介者を切り取りwc、すべてのファイル名を指定して呼び出します。

wc -l `find . -name "*.php"`

または、現代の構文では:

wc -l $(find . -name "*.php")

ディレクトリ名またはファイル名にスペースが含まれていない限り、機能します。そして、あなたが数万のファイルを持っていない限り(現代のシェルは本当に長いコマンドラインをサポートしています)。プロジェクトには74個のファイルがあるため、拡張する余地は十分にあります。


これ好き!ハイブリッドC / C ++環境の場合:wc -l `find . -type f \( -name "*.cpp" -o -name "*.c" -o -name "*.h" \) -print`
Bram

それがトップアンサーではなかったのには驚きました
ms4720

3

これらすべての複雑で覚えにくいコマンドは必要ありません。line-counterというツールが必要です。

簡単な概要

これがツールの入手方法です

$ pip install line-counter

lineコマンドを使用して、現在のディレクトリの下のファイル数と行数を取得します(再帰的に)

$ line
Search in /Users/Morgan/Documents/Example/
file count: 4
line count: 839

詳細が必要な場合は、を使用してくださいline -d

$ line -d
Search in /Users/Morgan/Documents/Example/
Dir A/file C.c                                             72
Dir A/file D.py                                           268
file A.py                                                 467
file B.c                                                   32
file count: 4
line count: 839

そして、このツールの最高の部分は、あなたが追加できることです .gitignore設定ファイルのようにことです。「.gitignore」で行うのと同じように、カウントするファイルの種類を選択または無視するルールを設定できます。

詳細と使用法はこちら:https : //github.com/MorganZhang100/line-counter


3

ファイルが多すぎる場合は、合計行数を探すだけの方がよいでしょう。

find . -name '*.php' | xargs wc -l | grep -i ' total' | awk '{print $1}'

2

少なくともOS Xでは、他のいくつかの回答にリストされているfind + xarg + wcコマンドは、大きなリストで「合計」を数回出力し、完全な合計はありません。次のコマンドを使用して、.cファイルの合計を1つ取得できました。

find . -name '*.c' -print0 |xargs -0 wc -l|grep -v total|awk '{ sum += $1; } END { print "SUM: " sum; }'

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.