Как рекурсивно посчитать все строки кода в директории?
У нас есть приложение на PHP, и нам нужно посчитать все строки кода в определенном каталоге и его подкаталогах.
Мы не хотим игнорировать комментарии, так как нам просто нужно получить общее представление о количестве строк.
Команда <code>wc -l *.php</code>
отлично работает для заданного каталога, но она игнорирует подкаталоги. Я думал, что следующая команда может помочь, но она возвращает 74, что явно не соответствует истине:
find . -name '*.php' | wc -l
Каков правильный синтаксис для рекурсивного подсчета всех файлов в каталоге?
5 ответ(ов)
Данный однострочник подсчитывает количество строк во всех файлах с расширением .php
в текущем каталоге и его подкаталогах. Вот как он работает:
( find ./ -name '*.php' -print0 | xargs -0 cat ) | wc -l
find ./ -name '*.php' -print0
— эта команда ищет файлы с расширением.php
в текущем каталоге и подкаталогах и выводит их имена, разделяя их нулевым байтом (что позволяет корректно обрабатывать имена файлов с пробелами).xargs -0 cat
—xargs
берет результаты командыfind
, обрабатывая нулевые байты как разделители, и передает их в командуcat
, которая объединяет содержимое всех найденных файлов.| wc -l
— в конце через конвейер передается вывод командыcat
, иwc -l
подсчитывает количество строк во всех этих файлах, выводя в результате одно число.
Таким образом, данный однострочник эффективно подсчитывает строки в файлах .php
, не обращая внимания на пробелы в именах файлов.
Если вы используете достаточно свежую версию Bash (или ZSH), это намного проще:
wc -l **/*.php
В оболочке Bash для этого необходимо включить опцию globstar
, иначе оператор **
не будет работать рекурсивно. Чтобы активировать эту настройку, выполните команду:
shopt -s globstar
Чтобы сделать это изменение постоянным, добавьте эту команду в один из файлов инициализации (~/.bashrc
, ~/.bash_profile
и т.д.).
На Unix-подобных системах есть утилита под названием cloc
, которая предоставляет статистику по коду.
Я запустил её на случайной директории в нашем проекте, и она выдала следующий результат:
59 текстовых файлов.
56 уникальных файлов.
5 файлов игнорируется.
http://cloc.sourceforge.net v 1.53 T=0.5 s (108.0 файлов/с, 50180.0 строк/с)
-------------------------------------------------------------------------------
Язык файлы пустые строки комментарии код
-------------------------------------------------------------------------------
C 36 3060 1431 16359
Заголовки C/C++ 16 689 393 3032
Makefile 1 17 9 54
Определение Teamcenter 1 10 0 36
-------------------------------------------------------------------------------
Итого: 54 3776 1833 19481
-------------------------------------------------------------------------------
Если у вас остались вопросы по поводу использования cloc
, не стесняйтесь спрашивать!
Вы не указали, сколько файлов имеется или какой ожидается результат.
Возможно, вам подойдет следующий вариант:
find . -name '*.php' | xargs wc -l
Эта команда действительно будет суммировать количество строк во всех файлах с расширением .php
в указанной директории и подкаталогах, а не выводить количество строк по каждому файлу отдельно.
Ваш пример команды:
$ find . -name '*.php' | xargs cat | wc -l
Дополнительный период .
в начале указывает find
искать файлы начиная с текущей директории (где вы находитесь в терминале).
Если вы хотите получить количество строк для каждого файла по отдельности, вы можете использовать следующую команду:
$ find . -name '*.php' -exec wc -l {} +
Эта команда использует -exec
опцию, которая позволяет выполнить wc -l
для каждого найденного файла, что и даст вам количество строк в каждом файле.
Как выводить команды оболочки по мере их выполнения
Назначение значений по умолчанию для переменных оболочки одной командой в bash
Как указать приватный SSH-ключ для выполнения команды shell в Git?
Как сделать паузу в shell-скрипте на одну секунду перед продолжением?
Как использовать 'grep' для непрерывного потока?