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?
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.
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.
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.).
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
-------------------------------------------------------------------------------
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
-------------------------------------------------------------------------------
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
Encore une autre variante :)
$ find -name '*.php' | xargs cat | wc -l
Edit: cela donnera la somme totale, au lieu de fichier par fichier.
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
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]'`
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.
É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 }'
pour les sources uniquement:
wc `find`
pour filtrer, utilisez simplement grep
wc `find | grep .php$`
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
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"
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}'
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.
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 !!!)
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.
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
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
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.
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
Pour Windows, l'outil simple et rapide est LocMetrics.
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"`
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
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
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; }'
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.
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.
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.
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
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
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:
$cd directory
$wc -l* | sort -nr
très simplement
find /path -type f -name "*.php" | while read FILE
do
count=$(wc -l < $FILE)
echo "$FILE has $count lines"
done
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
)
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.
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:
find
)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
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)
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}'
cat \`find . -name "*.php"\` | wc -l
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