web-dev-qa-db-fra.com

Comment compter toutes les lignes de code d'un répertoire de manière récursive?

Nous avons une application PHP et souhaitons compter toutes les lignes de code dans un répertoire spécifique et ses sous-répertoires. Nous n'avons pas besoin d'ignorer les commentaires, nous essayons simplement d'avoir une idée approximative. 

wc -l *.php 

Cette commande fonctionne très bien dans un répertoire donné, mais ignore les sous-répertoires. Je pensais que cela pourrait fonctionner, mais il en revient 74, ce qui n'est certainement pas le cas ...

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

Quelle est la syntaxe correcte pour alimenter tous les fichiers? 

1384
user77413

Essayez:

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

L'outil SLOCCount peut également aider.

Cela donnera un nombre de lignes source de code précis pour la hiérarchie À laquelle vous le dirigez, ainsi que quelques statistiques supplémentaires.

2340
Peter Elespuru

Pour un autre one-liner:

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

fonctionne sur les noms avec des espaces, ne génère qu'un seul nombre.

420
Shizzmo

Si vous utilisez une version relativement récente de Bash (ou ZSH), c'est beaucoup plus simple:

wc -l **/*.php

Dans Bash Shell, l'option globstar doit être définie, sinon l'opérateur ** glob n'est pas récursif. Pour activer ce paramètre, lancez

shopt -s globstar

Pour le rendre permanent, ajoutez-le à l'un des fichiers d'initialisation (~/.bashrc, ~/.bash_profile, etc.).

363
Michael Wild

Vous pouvez utiliser l'utilitaire cloc qui est construit à cette fin. Il indique chaque quantité de lignes dans chaque langue, ainsi que le nombre de commentaires, etc. CLOC est disponible sous Linux, Mac et Windows.

Exemple d'utilisation et de sortie:

$ 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
-------------------------------------------------------------------------------
264
simao

Sur les systèmes de type UNIX, il existe un outil appelé cloc qui fournit des statistiques de code. 

J'ai couru dans un répertoire aléatoire dans notre base de code, il dit:

      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
-------------------------------------------------------------------------------
91
Calmarius

Vous n’avez pas spécifié le nombre de fichiers présents ou la sortie souhaitée .. Est-ce ce que vous recherchez:

find . -name '*.php' | xargs wc -l
32
Paweł Polewicz

Encore une autre variante :)

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

Edit: cela donnera la somme totale, au lieu de fichier par fichier.

21
Motiejus Jakštys

POSIX

Contrairement à la plupart des autres réponses ici, elles fonctionnent sur n’importe quel système POSIX, pour n’importe quel nombre de fichiers et avec tous les noms de fichiers (sauf indication contraire).


Lignes dans chaque fichier:

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 {} +

Lignes dans chaque fichier, triées par chemin d'accès

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

Lignes dans chaque fichier, triées par nombre de lignes, décroissant

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

Nombre total de lignes dans tous les fichiers

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

Plus commun et simple en ce qui me concerne, supposons que vous ayez besoin de compter des fichiers d’extensions de noms différentes (par exemple, des fichiers natifs).

wc `find . -name '*.[h|c|cpp|php|cc]'`
18
sergeych

Il existe un petit outil appelé sloccount pour compter les lignes de code dans le répertoire. Il convient de noter qu'il en fait plus que vous ne le souhaitez car il ignore les lignes/commentaires vides, regroupe les résultats par langage de programmation et calcule des statistiques.

17
sebasgo

Étonnamment, il n'y a pas de réponse basée sur les -exec et awk de find. Et c'est parti:

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

Cet extrait trouve pour tous les fichiers (-type f). Pour rechercher par extension de fichier, utilisez -name:

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

pour les sources uniquement:

wc `find`

pour filtrer, utilisez simplement grep

wc `find | grep .php$`
11
kekszumquadrat

Un simple qui sera rapide, utilisera tout le pouvoir de recherche/filtrage de find, échouera quand il y aura trop de fichiers (dépassement d'arguments numériques), fonctionnera correctement avec des fichiers avec des symboles amusants dans leur nom, sans utiliser xargs, ne sera pas lance un nombre inutilement élevé de commandes externes (grâce à + pour find 's -exec). Voici:

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

Ce que vous voulez, c'est une simple boucle for:

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

En supposant que personne ne le verra jamais enterré à l'arrière… Pourtant, aucune des réponses à ce jour n'aborde le problème des noms de fichiers avec des espaces. En outre, tous ceux qui utilisent xargs sont susceptibles d'échouer si la longueur totale des chemins de l'arborescence dépasse la taille limite de l'environnement Shell (la valeur par défaut est de quelques mégaoctets sous Linux). En voici un qui résout ces problèmes de manière assez directe. Le sous-shell s'occupe des fichiers avec des espaces. La awk totalise le flux de sorties de fichiers individuels wc, vous ne devriez donc jamais manquer d’espace. Il limite également la exec aux fichiers (répertoires ignorés):

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

Je sais que la question porte la marque bash , mais il semble que le problème que vous essayez de résoudre soit également lié à PHP.

Sebastian Bergmann a écrit un outil appelé PHPLOC qui fait ce que vous voulez et qui vous donne en outre un aperçu de la complexité d'un projet. Voici un exemple de son rapport:

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

Comme vous pouvez le constater, les informations fournies sont beaucoup plus utiles du point de vue d'un développeur, car elles peuvent vous indiquer grossièrement la complexité d'un projet avant de commencer à l'utiliser.

7
Ja͢ck

WC -L? mieux utiliser GREP -C ^

wc -l? Faux! La commande wc compte les nouvelles lignes de codes, pas lignes! Lorsque la dernière ligne du fichier ne se termine pas par un nouveau code de ligne, cela ne comptera pas!

si vous voulez toujours compter les lignes, utilisez grep -c ^ , exemple complet:

#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

enfin, faites attention au piège wc -l (compte entre, pas de lignes !!!)

5
Znik

C’est très facile avec zsh globs:

wc -l ./**/*.php

Si vous utilisez bash, il vous suffit de mettre à niveau. Il n'y a absolument aucune raison d'utiliser bash.

4
HappyFace

Si vous souhaitez que vos résultats soient triés par nombre de lignes, vous pouvez simplement ajouter | sort ou | sort -r (-r par ordre décroissant) à la première réponse, comme suit:

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

Quelque chose de différent:

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

Cela fonctionne très bien, mais vous devez avoir au moins un fichier *.php dans le dossier actuel ou l'un de ses sous-dossiers, ou bien wc stalls

4
nav

Si vous n'avez besoin que du nombre total de lignes dans vos fichiers PHP, vous pouvez utiliser une commande très simple d'une ligne, même sous Windows, si vous avez installé GnuWin32. Comme ça:

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

Vous devez spécifier où se trouve exactement le fichier find.exe, sinon le fichier FIND.EXE fourni par Windows (à partir des anciennes commandes de type DOS) sera exécuté, car il figure probablement avant le fichier GnuWin32 dans l'environnement PATH et a des paramètres et des résultats différents.

Veuillez noter que dans la commande ci-dessus, vous devez utiliser des guillemets arrières, et non des guillemets simples.

3
Neven Boyanov

Donner d’abord les fichiers les plus longs (c’est-à-dire que ces longs fichiers nécessitent un peu d’amour de refactoring?) Et exclure certains répertoires de fournisseurs

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

Pour Windows, l'outil simple et rapide est LocMetrics.

3
walv

bien que j'aime les scripts, je préfère celui-ci, car il affiche également un résumé par fichier tant que le total

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

Hors ligne vierge 

find . -name "*.php" | xargs grep -v -c '^$' | awk 'BEGIN {FS=":"} { $cnt = $cnt + $2} END {print $cnt}'

Y compris les lignes vierges:

find . -name "*.php" | xargs wc -l
2

Vous n'avez pas besoin de toutes ces commandes compliquées et difficiles à retenir. Vous avez juste besoin d'un outil appelé line-counter.

Un aperçu rapide

Voici comment vous obtenez l'outil

$ pip install line-counter

Utilisez la commande line pour obtenir le nombre de fichiers et le nombre de lignes dans le répertoire en cours (récursivement)

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

Si vous voulez plus de détails, utilisez simplement 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

Et la meilleure partie de cet outil est que vous pouvez y ajouter .gitignore comme un fichier de configuration. Vous pouvez configurer des règles pour sélectionner ou ignorer le type de fichiers à compter, comme ce que vous faites dans '.gitignore'.

Plus de description et d'utilisation ici: https://github.com/MorganZhang100/line-counter

2
Morgan Zhang

Sur OS X au moins, les commandes find + xarg + wc répertoriées dans certaines des autres réponses impriment le "total" plusieurs fois sur des listes volumineuses, et aucun total n'est donné. J'ai pu obtenir un total unique pour les fichiers .c en utilisant la commande suivante:

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

2
Doug Richardson

Si vous voulez garder les choses simples, supprimez l’intermédiaire et appelez simplement wc avec tous les noms de fichiers:

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

Ou dans la syntaxe moderne:

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

Fonctionne tant qu'il n'y a pas d'espaces dans les noms de répertoire ou les noms de fichiers. Et tant que vous n’avez pas des dizaines de milliers de fichiers (les shells modernes supportent des lignes de commande très longues). Votre projet contient 74 fichiers, vous avez donc beaucoup de place pour grandir.

2
alexis

Si vous êtes sous Linux (et je suppose que vous l'êtes), je recommande mon outil polyglot . Il est considérablement plus rapide que sloccount ou cloc et est plus complet que sloccount

Vous pouvez l'invoquer avec

poly .

ou

poly

il est donc beaucoup plus convivial que certains scripts bash compliqués.

2
user8174234

J'ai utilisé ce script en ligne que je lance à partir du répertoire de src-project:

 for i in $(find . -type f); do rowline=$(wc -l $i | cut -f1 -d" "); file=$(wc -l $i | cut -f2 -d" "); lines=$((lines + rowline)); echo "Lines["$lines"] " $file "has "$rowline"rows."; done && unset lines

Cela produit cette sortie:

Lines[75]  ./Db.h has 75rows.
Lines[143]  ./Db.cpp has 68rows.
Lines[170]  ./main.cpp has 27rows.
Lines[294]  ./Sqlite.cpp has 124rows.
Lines[349]  ./Sqlite.h has 55rows.
Lines[445]  ./Table.cpp has 96rows.
Lines[480]  ./DbError.cpp has 35rows.
Lines[521]  ./DbError.h has 41rows.
Lines[627]  ./QueryResult.cpp has 106rows.
Lines[717]  ./QueryResult.h has 90rows.
Lines[828]  ./Table.h has 111rows.
2
Luca Davanzo

Je voulais vérifier plusieurs types de fichiers, et j'étais trop paresseux pour calculer le total manuellement. Donc, je l'utilise maintenant pour obtenir le total en une fois.

find . -name '*.js' -or -name '*.php' | xargs wc -l | grep 'total'  | awk '{ SUM += $1; print $1} END { print "Total text lines in PHP and JS",SUM }'

79351
15318
Total des lignes de texte dans PHP et JS 94669

Cela vous permet de chaîner plusieurs types d'extensions que vous souhaitez filtrer. Ajoutez-les simplement dans la partie -name '*.js' -or -name '*.php' et modifiez éventuellement le message de suppression à votre guise

1
Tschallacka

commencez par changer le répertoire dans lequel vous voulez connaître le nombre de lignes. Par exemple, si je veux connaître le nombre de lignes dans tous les fichiers du répertoire nommé sample. donner $cd sample. puis essayez la commande $wc -l * cela retournera le nombre de lignes pour chaque fichier ainsi que le nombre total de lignes dans le répertoire complet à la fin

1
venky513

Encore une autre commande pour obtenir la somme de tous les fichiers (Linux bien sur)

find ./ -type f -exec wc -l {}  \; | cut -d' ' -f1 | paste -sd+ | bc

Principale différence par rapport aux autres réponses: 

  1. en utilisant find -exec
  2. en utilisant coller (avec coupe)
  3. en utilisant bc  
1
AJed
$cd directory
$wc -l* | sort -nr
1
sree

très simplement

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

J'ai une boîte occupée installée sur mon système Windows. Alors voici ce que j'ai fait.

ECHO OFF
for /r %%G in (*.php) do (
busybox grep . "%%G" | busybox wc -l
) 
1
shyam

Je le fais comme ça:

voici l'implémentation du fichier lineCount.c:

#include <stdio.h>
#include <string.h>
#include <stdlib.h> 

int getLinesFromFile(const char*);

int main(int argc, char* argv[]) {
   int total_lines = 0; 
   for(int i = 1; i < argc; ++i) {
       total_lines += getLinesFromFile(argv[i]); // *argv is a char*        
   }    

   printf("You have a total of %d lines in all your file(s)\n",    total_lines);
   return 0;
}


int getLinesFromFile(const char* file_name) {
    int lines = 0;
    FILE* file;
    file = fopen(file_name, "r");
    char c = ' ';
    while((c=getc(file)) != EOF) if(c == '\n') ++lines;
    fclose(file);   
    return lines;
}

Ouvrez maintenant la ligne de commande:

et tapez gcc lineCount.c puis tapez ./a.out *.txt Cela affichera le nombre total de lignes de fichiers se terminant par .txt dans votre répertoire.

1
Moshe Rabaev

Semblable à réponse de Shizzmo , mais plus laid et plus précis. Si vous l'utilisez souvent, modifiez-le en conséquence et mettez-le dans un script.

Cet exemple:

  1. Exclut correctement les chemins qui ne sont pas votre code (pas du tout traversés par find)
  2. Filtre les extensions composées et autres fichiers que vous souhaitez ignorer
  3. Inclut uniquement les fichiers réels des types que vous spécifiez
  4. Ignore les lignes vierges
  5. Donne un nombre unique au total
find . \! \( \( -path ./lib -o -path ./node_modules -o -path ./vendor -o -path ./any/other/path/to/skip -o -wholename ./not/this/specific/file.php -o -name '*.min.js' -o -name '*.min.css' \) -Prune \) -type f \( -name '*.php' -o -name '*.inc' -o -name '*.js' -o -name '*.scss' -o -name '*.css' \) -print0 | xargs -0 cat | grep -v '^$' | wc -l
0
Walf

En voici un exemple flexible utilisant Python plus ancien _ (fonctionne au moins en Python 2.6 _) intégrant le charmant liner de @ Shizzmo. Remplissez simplement la liste types avec les types de fichiers que vous voulez compter dans le dossier source, et laissez voler:

#!/usr/bin/python

import subprocess

rcmd = "( find ./ -name '*.%s' -print0 | xargs -0 cat ) | wc -l"
types = ['c','cpp','h','txt']

sum = 0
for el in types:
    cmd = rcmd % (el)
    p = subprocess.Popen([cmd],stdout=subprocess.PIPE,Shell=True)
    out = p.stdout.read().strip()
    print "*.%s: %s" % (el,out)
    sum += int(out)
print "sum: %d" % (sum)
0
fyngyrz

Si les fichiers sont trop nombreux, il est préférable de rechercher le nombre total de lignes.

find . -name '*.php' | xargs wc -l | grep -i ' total' | awk '{print $1}'
0
bharath
cat \`find . -name "*.php"\` | wc -l
0
Bjarni Herjolfsson

Je peux aussi bien ajouter une autre entrée OS X, celle-ci utilisant plain old avec exec (ce que je préfère par rapport à xargs, car j’ai déjà vu des résultats étranges dans de très grands ensembles de résultats find avec xargs). Comme cela concerne OS X, j’ai également ajouté le filtrage aux fichiers .h ou .m - veillez à les copier jusqu’à la fin! 

find ./ -type f -name "*.[mh]" -exec wc -l {}  \; | sed -e 's/[ ]*//g' | cut -d"." -f1 | paste -sd+ - | bc