как посчитать все строки кода в каталоге рекурсивно?

<p>у нас есть приложение php, и мы хотим подсчитать все строки кода в определенном каталоге и его подкаталогах. нам не нужно игнорировать комментарии, так как мы просто пытаемся получить грубое представление. </p><pre><code>wc -l *.php </code></pre><p>эта команда прекрасно работает в данном каталоге, но игнорирует подкаталоги. я думал, что это может сработать, но возвращается 74, что, безусловно, не так ...</p><pre><code>find . -name '*.php' | wc -l </code></pre><p>какой правильный синтаксис для подачи во всех файлах? </p>

<p><strong>пытаться:</strong></p><pre><code>find . -name '*.php' | xargs wc -l </code></pre><p><strong> <a href="http://www.dwheeler.com/sloccount/">инструмент sloccount</a> </strong> также может помочь.</p><p>он даст точные исходные строки кода для любой иерархии на которую вы указываете, а также некоторые дополнительные характеристики.</p>

<p>для другого однострочника:</p><pre><code>( find ./ -name '*.php' -print0 | xargs -0 cat ) | wc -l </code></pre><p>работает с именами с пробелами, выводит только одно число.</p>

<p>если вы используете довольно свежую версию bash (или zsh), это намного проще:</p><pre><code>wc -l **/*.php </code></pre><p>в bash shell это требует установки опции <code>globstar</code>, в противном случае оператор <code>**</code> glob не является рекурсивным. чтобы включить этот параметр, выполните команду</p><pre><code>shopt -s globstar </code></pre><p>чтобы сделать это постоянным, добавьте его в один из файлов инициализации (<code>~/.bashrc</code>, <code>~/.bash\_profile</code> и т.д.).</p>

<p>в unix-подобных системах есть инструмент под названием <code>cloc</code>, который предоставляет статистику кода. </p><p>я наткнулся на случайный каталог в нашей кодовой базе:</p><pre><code> 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 ------------------------------------------------------------------------------- </code></pre>

<p>вы не указали, сколько файлов там или какой желаемый результат .. это то, что вы ищете:</p><pre><code>find . -name '*.php' | xargs wc -l </code></pre>

<p>еще один вариант :)</p><pre><code>$ find -name '.php' | xargs cat | wc -l правка: это даст общую сумму, а не файл за файлом.

<strong>posix</strong>в отличие от большинства других ответов здесь, они работают в любой системе 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]' 

существует небольшой инструмент под названием <a href="http://www.dwheeler.com/sloccount/"><strong>sloccount</strong> для подсчета строк кода в каталоге. следует отметить, что он делает больше, чем вы хотите, так как он игнорирует пустые строки/комментарии, группирует результаты по языкам программирования и вычисляет некоторую статистику.

удивительно, но нет ответа на основании -exec и awk поиска. вот так:find . -type f -exec wc -l {} ; | awk '{ sum += $0} end { print sum }' </code></pre><p>этот фрагмент находит все файлы (<code>-type f</code>). чтобы найти по расширению файла, используйте <code>-name</code>:</p><pre><code>find . -name *.py -exec wc -l {} \; | awk '{ sum += $0} end { print sum }' 

только для источников:wc find для фильтрации, просто используйте grepwc find | grep .php$` </code></pre>

<p>простой, который будет быстрым, будет использовать все возможности поиска/фильтрации <code>find</code>, не подведет, когда слишком много файлов (переполнение аргументов чисел), отлично работает с файлами со смешными символами в имени, без использования <code>xargs</code>, не будет запускать бесполезно большое количество внешних команд (спасибо <code>+</code> за <code>find</code>'s <code>-exec</code>). ну вот:</p><pre><code>find . -name '*.php' -type f -exec cat -- {} + | wc -l </code></pre>

<p>то, что вы хотите, это простой <code>for</code> цикл:</p><pre><code>total\_count=0 for file in $(find . -name .php -print) do count=$(wc -l $file) let total_count+=count done echo "$total\_count" </code></pre>

<p>полагаю, никто никогда не увидит, что это похоронено сзади ... и все же ни один из ответов до сих пор не касается проблемы имен файлов с пробелами. кроме того, все, которые используют <code>xargs</code>, могут потерпеть неудачу, если общая длина путей в дереве превышает ограничение размера среды shell (по умолчанию в linux несколько мегабайт). вот тот, который решает эти проблемы довольно прямо. подоболочка заботится о файлах с пробелами. <code>awk</code> суммирует поток отдельных выходных файлов <code>wc</code>, поэтому никогда не должно заканчиваться свободное место. он также ограничивает <code>exec</code> только для файлов (пропуская каталоги):</p><pre><code>find . -type f -name '*.php' -exec bash -c 'wc -l "$0"' {} ; | awk '{s+=$1} end {print s}' </code></pre>

<p>я знаю, что вопрос помечен как <a href="/questions/tagged/bash">bash</a> , но похоже, что проблема, которую вы пытаетесь решить, также связана php.</p><p>себастьян бергманн написал инструмент под названием <a href="https://github.com/sebastianbergmann/phploc">phploc</a> , который делает то, что вы хотите, и, кроме того, предоставляет вам обзор сложности проекта. вот пример его отчета:</p><pre class="lang-none prettyprint-override"><code>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 </code></pre><p>как видите, предоставленная информация намного полезнее с точки зрения разработчика, поскольку она может примерно сказать вам, насколько сложен проект, прежде чем вы начнете с ним работать.</p>

<blockquote> <p>wc -l? лучше использовать grep -c ^</p> </blockquote><p>wc -l? <strong> неправильно! команда </strong> wc считает коды новых строк,<strong> не </strong>строк! когда последняя строка в файле не заканчивается кодом новой строки,<strong> это не засчитывается! </strong></p><p>если вы все еще хотите считать строки, используйте<strong> grep -c ^ </strong>, полный пример:</p><pre><code>#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<strong> (считает количество, а не количество строк !!!) </strong>

с zsh globs это очень просто:wc -l .//.php если вы используете bash, вам просто нужно обновить. нет абсолютно никакой причины использовать bash.

если вы хотите, чтобы результаты сортировались по количеству строк, вы можете просто добавить | sort или | sort -r (-r в порядке убывания) к первому ответу, например так:find . -name '.php' | xargs wc -l | sort -r 

что-то другое:wc -l tree -if --noreport | grep -e'.php$'` </code></pre><p>это работает нормально, но вам нужно иметь хотя бы один файл <code>*.php</code> в текущей папке или в одной из ее подпапок, иначе <code>wc</code> останавливается</p>

<p>если вам нужно только общее количество строк в, скажем, ваших php файлах, вы можете использовать очень простую однострочную команду даже под windows, если у вас установлен gnuwin32. как это:</p><pre><code>cat `/gnuwin32/bin/find.exe . -name *.php` | wc -l </code></pre><p>вам нужно указать, где именно находится find.exe, иначе будет предоставлен windows find.exe (из старых dos-подобных команд), так как он, вероятно, перед gnuwin32 в среде path и имеет другие параметры и результаты.</p><p>обратите внимание, что в приведенной выше команде вы должны использовать обратные кавычки, а не одинарные.</p>

<p>сначала выдает самые длинные файлы (т. е. может быть, эти длинные файлы нуждаются в некотором рефакторинге?), за исключением некоторых каталогов поставщиков:</p><pre><code> find . -name '*.php' | xargs wc -l | sort -nr | egrep -v "libs|tmp|tests|vendor" | less </code></pre>

<p>для <strong>windows</strong> простым и быстрым инструментом является <strong> <a href="http://www.locmetrics.com">locmetrics</a> </strong>.</p>

<p>в то время как мне нравятся сценарии, я предпочитаю этот, так как он также показывает сводку по каждому файлу, пока общая</p><pre><code>wc -l `find . -name "*.php"` </code></pre>

<p>исключая пустую строку </p><pre><code>find . -name "*.php" | xargs grep -v -c '^$' | awk 'begin {fs=":"} { $cnt = $cnt + $2} end {print $cnt}' включая пустые строки:find . -name ".php" | xargs wc -l 

вам не нужны все эти сложные и трудно запоминающиеся команды. вам просто нужен инструмент с именем <strong>line-counter</strong>.<strong>краткий обзор</strong>вот как вы получаете инструмент$ pip install line-counter </code></pre><p>используйте команду <code>line</code>, чтобы получить количество файлов и количество строк в текущем каталоге (рекурсивно)</p><pre><code>$ 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 </code></pre><p>и лучшая часть этого инструмента - вы можете добавить к нему <code>.gitignore</code>, например, файл конфигурации. вы можете настроить правила, чтобы выбирать или игнорировать, какие типы файлов считать так же, как в «.gitignore».</p><p>более подробное описание и использование здесь: <a href="https://github.com/morganzhang100/line-counter">https://github.com/morganzhang100/line-counter</a> </p>

<p>по крайней мере, в os x команды find + xarg + wc, перечисленные в некоторых других ответах, печатают «total» несколько раз в больших списках, и полная сумма не указывается. мне удалось получить единый итог для файлов .c с помощью следующей команды:</p><p><code>find . -name '*.c' -print0 |xargs -0 wc -l|grep -v total|awk '{ sum += $1; } end { print "sum: " sum; }'

если вы хотите сохранить простоту, вырежьте посредника и просто вызовите wc со всеми именами файлов:wc -l find . -name ".php" или в современном синтаксисе:wc -l $(find . -name "*.php") </code></pre><p>работает, пока нет пробелов ни в одном из имен каталогов или имен файлов. и до тех пор, пока у вас нет десятков тысяч файлов (современные оболочки поддерживают очень длинные командные строки). в вашем проекте 74 файла, поэтому у вас есть много возможностей для роста.</p>

<p>если вы работаете в linux (и я так понимаю), я рекомендую мой инструмент <a href="http://github.com/vmchale/polyglot">polyglot</a> . он значительно быстрее, чем <code>sloccount</code> или <code>cloc</code>, и он более функциональный, чем <code>sloccount</code>. </p><p>вы можете вызвать его с</p><pre><code>poly . </code></pre><p>или же</p><pre><code>poly </code></pre><p>так что это намного удобнее для пользователя, чем какой-то замысловатый скрипт bash.</p>

<p>я использовал этот встроенный скрипт, который я запускаю из каталога src-project:</p><pre><code> 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. 

я хотел проверить несколько типов файлов, и мне было лениво вычислять сумму вручную. поэтому я использую это сейчас, чтобы получить общее количество за один раз.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 }' <blockquote> 79351 15318 всего строк текста в php и js 94669 </blockquote>это позволяет вам связывать несколько типов расширений, по которым вы хотите фильтровать. просто добавьте их в часть -name '.js' -or -name '.php' и, возможно, измените сообщение по своему вкусу.

сначала измените каталог, в который вы хотите узнать количество строк. например, если я хочу знать количество строк во всех файлах каталога с именем sample. дать $cd sample</code>. затем попробуйте команду <code>$wc -l , которая вернет количество строк для каждого файла, а также общее количество строк во всем каталоге в конце

еще одна команда для получения суммы всех файлов (linux, конечно)find ./ -type f -exec wc -l {} ; | cut -d' ' -f1 | paste -sd+ | bc основное отличие от других ответов:  используя find -exec ,  используя паста (с разрезом) ,  используя bc   

$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 

я имею занятую коробку установленную в моей системе windows. итак, вот что я сделал.echo off for /r %%g in (.php) do ( busybox grep . "%%g" | busybox wc -l ) 

я делаю это так:вот реализация файла 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 в вашем каталоге.

если файлов слишком много, лучше просто посмотреть общее количество строк.find . -name '.php' | xargs wc -l | grep -i ' total' | awk '{print $1}' </code></pre>

<pre><code>cat \`find . -name "*.php"\` | wc -l </code></pre>

<p>я также могу добавить еще одну запись os x, в которой используется простая старая находка с exec (которую я предпочитаю использовать xargs, поскольку в прошлом я видел странные результаты из очень больших наборов результатов <code>find</code> с xargs). поскольку это для os x, я также добавил в фильтрацию к файлам .h или .m - убедитесь, что скопировали все до конца! </p><pre><code>find ./ -type f -name "*.[mh]" -exec wc -l {} \; | sed -e 's/[ ]*//g' | cut -d"." -f1 | paste -sd+ - | bc </code></pre>