У нас есть приложение PHP и мы хотим подсчитать все строки кода под определенным каталогом и его подкаталогами. Нам не нужно игнорировать комментарии, так как мы просто пытаемся получить приблизительную идею.
wc -l *.php
Эта команда отлично работает в пределах заданного каталога, но игнорирует подкаталоги. Я думал, что это может сработать, но оно возвращается 74, что определенно не так...
find . -name '*.php' | wc -l
Какой правильный синтаксис для подачи во всех файлах?
Попытка:
find . -name '*.php' | xargs wc -l
Инструмент SLOCCount также может помочь.
Это даст точные исходные строки кода для любого иерархию, на которую вы указываете ее, а также некоторые дополнительные параметры.
Для другого однострочного:
( find ./ -name '*.php' -print0 | xargs -0 cat ) | wc -l
работает с именами с пробелами, выводит только одно число.
-print0
/ -0
Если использовать по-прежнему последнюю версию Bash (или ZSH), она намного проще:
wc -l **/*.php
В оболочке Bash для этого требуется установить параметр globstar
, в противном случае оператор **
glob не является рекурсивным. Чтобы включить этот параметр, выполните
shopt -s globstar
Чтобы сделать это постоянным, добавьте его в один из файлов инициализации (~/.bashrc
, ~/.bash_profile
и т.д.).
globstar
был установлен, чтобы это работало.
Вы можете использовать утилиту 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
-------------------------------------------------------------------------------
В 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
-------------------------------------------------------------------------------
Вы не указали, сколько там файлов или какой желаемый результат. Это то, что вы ищите:
find . -name '*.php' | xargs wc -l
Еще одна вариация:)
$ find -name '*.php' | xargs cat | wc -l
Изменить: это даст общую сумму, а не файл за файлом.
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
Более распространенный и простой, как и для меня, предположим, что вам нужно подсчитывать файлы с разными расширениями имен (скажем, и туземными)
wc `find . -name '*.[h|c|cpp|php|cc]'`
Для подсчета строк кода в каталоге есть небольшой инструмент sloccount. Следует отметить, что он делает больше, чем вы хотите, поскольку он игнорирует пустые строки/комментарии, группирует результаты на язык программирования и вычисляет некоторые статистические данные.
Удивительно, но нет ответа на основе поиска -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 }'
find . -name '*.c' -print0 |xargs -0 wc -l
. Тем не менее, этот более быстрый метод (по крайней мере, в OS X) приводит к тому, что выводит «total» несколько раз, поэтому для получения правильного итога требуется дополнительная фильтрация (подробности я опубликовал в своем ответе).
Простое, быстрое, будет использовать все возможности поиска/фильтрации find
, не сработает, если слишком много файлов (переполнение числа аргументов), отлично работать с файлами со смешными символами в их имени, без используя xargs
, не запускает бесполезно большое количество внешних команд (благодаря +
для find
-exec
). Вот вы:
find . -name '*.php' -type f -exec cat -- {} + | wc -l
\;
вместо +
поскольку я не знал об этом), этот ответ должен быть правильным.
только для источников:
wc `find`
для фильтрации, просто используйте grep
wc `find | grep .php$`
То, что вы хотите, это просто for
цикла:
total_count=0
for file in $(find . -name *.php -print)
do
count=$(wc -l $file)
let total_count+=count
done
echo "$total_count"
xargs
?
Угадав, что никто никогда не увидит, что это похоронено сзади... Тем не менее, ни один из ответов до сих пор не сталкивается с проблемой имен файлов с пробелами. Кроме того, все, использующие xargs
, терпят неудачу, если общая длина путей в дереве превышает ограничение по размеру оболочки оболочки (по умолчанию - несколько мегабайт в Linux). Вот тот, который исправляет эти проблемы довольно прямо. Подоболочка заботится о файлах с пробелами. awk
суммирует поток отдельных файлов wc
, поэтому никогда не должно заканчиваться пространство. Он также ограничивает файлы exec
только файлами (пропусками каталогов):
find . -type f -name '*.php' -exec bash -c 'wc -l "$0"' {} \; | awk '{s+=$1} END {print s}'
Вы также можете попробовать CLOC (требуется Perl)
Я знаю, что вопрос отмечен как bash, но кажется, что проблема, которую вы пытаетесь решить, также связана с PHP.
Себастьян Бергманн написал инструмент под названием 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
Как вы можете видеть, предоставленная информация намного более полезна с точки зрения разработчика, потому что она может примерно рассказать вам, насколько сложным является проект, прежде чем вы начнете работать с ним.
WC -L? лучше использовать GREP -C ^
wc -l? Неправильно! Команда wc подсчитывает новые коды строк, строки не! Когда последняя строка в файле не заканчивается новым кодом строки, это не будет считаться!
если вам все еще нужны строки подсчета, используйте 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 trap (количество входящих, а не строк!!!)
grep -c ^
вы подсчитываете количество неполных строк , и такие неполные строки не могут появиться в текстовом файле .
Это очень легко с zsh globs:
wc -l ./**/*.php
Если вы используете Bash, вам просто нужно обновить. Нет абсолютно никакой причины использовать bash.
Что-то другое:
wc -l `tree -if --noreport | grep -e'\.php$'`
Это отлично работает, но в текущей папке или одной из ее подпапок вам нужно иметь хотя бы один файл *.php
, иначе wc
stalls
Если вы хотите, чтобы ваши результаты сортировались по количеству строк, вы можете просто добавить | sort
или | sort -r
(-r
для убывающего порядка) к первому ответу, например:
find . -name '*.php' | xargs wc -l | sort -r
xargs wc -l
является числовым, на самом деле нужно будет использовать sort -n
или sort -nr
.
Для Windows простой и быстрый инструмент LocMetrics.
Выдавать самые длинные файлы (т.е. возможно, эти длинные файлы нуждаются в некоторой рефакторинговой любви?) и исключая некоторые каталоги поставщиков:
find . -name '*.php' | xargs wc -l | sort -nr | egrep -v "libs|tmp|tests|vendor" | less
Если вам нужно всего лишь общее количество строк, пусть говорят ваши PHP файлы, вы можете использовать очень простую однострочную команду даже под Windows, если у вас установлен GnuWin32. Вот так:
cat `/gnuwin32/bin/find.exe . -name *.php` | wc -l
Вам нужно указать, где именно находится find.exe, иначе Windows, на которой FIND.EXE(из старых DOS-подобных команд) будет выполняться, поскольку это, вероятно, до GnuWin32 в среде PATH и имеет разные параметры и результаты.
Обратите внимание, что в приведенной выше команде вы должны использовать обратные кавычки, а не одинарные кавычки.
Если вы работаете в Linux (и я так понимаю), я рекомендую мой инструмент polyglot. Это значительно быстрее, чем sloccount
или cloc
и это более функционально, чем sloccount
.
Вы можете вызвать его с
poly .
или же
poly
так что это гораздо более удобный для пользователя, чем какой-то замысловатый скрипт bash.
Вам не нужны все эти сложные и трудно запоминающиеся команды. Вам просто нужен инструмент с именем 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
Если вы хотите сохранить его простым, вырежьте посредника и просто вызовите wc
со всеми именами файлов:
wc -l `find . -name "*.php"`
Или в современном синтаксисе:
wc -l $(find . -name "*.php")
Работает до тех пор, пока в именах каталогов или именах файлов не будет пробелов. И до тех пор, пока у вас нет десятков тысяч файлов (современные оболочки поддерживают очень длинные командные строки). В вашем проекте 74 файла, поэтому у вас есть много возможностей для роста.
wc -l `find . -type f \( -name "*.cpp" -o -name "*.c" -o -name "*.h" \) -print`
Исключение пустой строки
find . -name "*.php" | xargs grep -v -c '^$' | awk 'BEGIN {FS=":"} { $cnt = $cnt + $2} END {print $cnt}'
Включая пустые строки:
find . -name "*.php" | xargs wc -l
в то время как мне нравятся сценарии, которые я предпочитаю, так как он также показывает сводку для каждого файла, если общий
wc -l `find . -name "*.php"`
Я использовал этот inline- script, который я запускаю из каталога 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
Это производит этот вывод:
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.
В OS X, по крайней мере, команды find + xarg + wc, перечисленные в некоторых других ответах, печатают "total" несколько раз в больших списках, и нет полной полной информации. Я смог получить одно общее количество файлов .c, используя следующую команду:
find . -name '*.c' -print0 |xargs -0 wc -l|grep -v total|awk '{ sum += $1; } END { print "SUM: " sum; }'
Я делаю это так:
здесь реализована реализация файла 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;
}
Теперь откройте командную строку:
и введите gcc lineCount.c
, затем введите ./a.out *.txt
Это отобразит общие строки файлов, заканчивающихся на .txt в вашем каталоге.
Сначала измените каталог, в который вы хотите узнать количество строк. например, если я хочу знать количество строк во всех файлах каталога с именем sample. дайте $cd sample
. затем попробуйте команду $wc -l *
которая вернет количество строк для каждого файла, а также общее количество строк во всем каталоге в конце
Я хотел проверить несколько типов файлов и был ленив, чтобы вычислить сумму вручную. Поэтому я использую это сейчас, чтобы получить общее количество за один раз.
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
Всего текстовых строк в PHP и JS 94669
Это позволяет вам связывать несколько типов расширений, которые вы хотите фильтровать. Просто добавьте их в часть -name '*.js' -or -name '*.php'
и, возможно, измените сообщение otuput по своему вкусу
Еще одна команда, чтобы получить сумму всех файлов (Linux, конечно)
find ./ -type f -exec wc -l {} \; | cut -d' ' -f1 | paste -sd+ | bc
Основное отличие от других ответов:
У меня есть загрузочный ящик, установленный в моей системе Windows. Итак, вот что я сделал.
ECHO OFF
for /r %%G in (*.php) do (
busybox grep . "%%G" | busybox wc -l
)
$cd directory
$wc -l* | sort -nr
очень просто
find /path -type f -name "*.php" | while read FILE
do
count=$(wc -l < $FILE)
echo "$FILE has $count lines"
done
Если файлов слишком много, лучше просто посмотреть на общее количество.
find . -name '*.php' | xargs wc -l | grep -i ' total' | awk '{print $1}'
Я также могу добавить еще одну запись в OS X, в которой используется простая старая находка с exec (которую я предпочитаю использовать с помощью xargs, поскольку я видел нечетные результаты из очень больших наборов результатов find
с xargs в прошлом). Поскольку это для OS X, я также добавил в фильтрацию в файлы .h или .m - обязательно скопируйте все до конца!
find ./ -type f -name "*.[mh]" -exec wc -l {} \; | sed -e 's/[ ]*//g' | cut -d"." -f1 | paste -sd+ - | bc
Это должно сделать то же самое, что и piping в xargs wc -l
, это может быть не так быстро.
t=0
for i in $(find . -name '*.php'); do
n=0
while read line; do
((n++)) && continue
done < $i
((t+=n))
echo "$n $i"
done
echo "$t total"
cat \`find . -name "*.php"\` | wc -l
find . -name '*.php' -o -name '*.inc' | xargs wc -l