підрахунок (непорожні) рядки коду в баші


151

Як в Bash я рахую кількість непорожніх рядків коду в проекті?


1
Дуже багато рішень нижче просто працюють для одного файлу (наприклад, foo.c). Будь-які думки щодо загальної кількості рядків у проекті (наприклад, багато файлів у структурі каталогів та виключення бінарних файлів)?
— розв’язання Пузлів

5
@solvingPuzzles Я думаю, що можу відповісти на цю частину. Для будь-якого рішення, яке працює на одному файлі, наприклад, "cat FILE | sed blah", ви можете працювати над багатьма файлами, замінивши "cat FILE" командою, в якій перераховані імена файлів, над якими можна працювати, наприклад "find. -Name" * .py '"та передайте" xargs cat ". напр. "find. -name '* .py' | xargs cat | sed '/ ^ \ s * $ / d' | wc -l"
— Джонатан Хартлі

2
@JonathanHartley @solvingPuzzles також є такі програми, як slocі clocтут, щоб зробити ці підрахунки рядків коду.
— AsTeR

ОП тут: Коли я вперше запитав цю проблему, "cloc" не дуже добре працював над кодом Python. У наш час це чудово.
— Джонатан Хартлі

cloc також доступний у вигляді модуля npm та економить багато часу.
— Кришна Ведула

Відповіді:


193
cat foo.c | sed '/^\s*$/d' | wc -l

І якщо ви вважаєте коментарі порожніми рядками:

cat foo.pl | sed '/^\s*#/d;/^\s*$/d' | wc -l

Хоча, це залежить від мови.


24
Не впевнений, чому ви там використовуєте кота. Використовуйте foo.c або foo.pl як ім'я файлу, щоб перейти до sed. sed '/ ^ \ s * $ / d' foo.c | wc -l
— Енді Лестер

28
Просто звичка. Я читаю трубопроводи зліва направо, це означає, що я зазвичай починаю з кота, потім дії, дії, дії тощо. Ясно, що кінцевий результат той самий.
— Майкл Креймер

32
Щоб зробити це для всіх файлів у всіх підпапках та виключити коментарі за допомогою '//', розкладіть цю команду до цього: find. -тип f -name '* .c' -exec cat {} \; | sed '/ ^ \ s * # / d; / ^ \ s * $ / d; / ^ \ s * \ / \ // d' | wc -l
— Benjamin Intal

11
Ви можете читати зліва направо без UUOC: < foo.pl sed 'stuff' | wc -l.
— jw013

22
Взагалі кажучи, UUOC не важливий, але читабельність - це.
— andersand

52
#!/bin/bash
find . -path './pma' -prune -o -path './blog' -prune -o -path './punbb' -prune -o -path './js/3rdparty' -prune -o -print | egrep '\.php|\.as|\.sql|\.css|\.js' | grep -v '\.svn' | xargs cat | sed '/^\s*$/d' | wc -l

Вищенаведене дасть вам загальну кількість рядків коду (видалені порожні рядки) для проекту (поточна папка та всі підпапки рекурсивно).

У наведених вище "./blog" "./punbb" "./js/3rdparty" та "./pma" - це папки, у яких я чорний список, оскільки я не писав у них код. Також .php, .as, .sql, .css, .js - це розширення файлів, які переглядаються. Будь-які файли з іншим розширенням ігноруються.


1
варіація для програми Rails: знайти. -path './log' -prune -o -path './trunk' -prune -o -ath './branches' -prune -o -ath './vendor' -prune -o -path './tmp '-прун -о -принт | egrep '\ .rb | \ .erb | \ .css | \ .js | \ .yml' | grep -v 'svn' | xargs cat | sed '/ ^ \ s * $ / d' | wc -l
— poseid

1
Вам потрібно додати $до grep ( ...\.js$|...), інакше він збігатиметься feature.js.swp.
— Xeoncross

Ви забули кріплення, тому воно містить неправильні файли. І ще простіша версія з прив’язкою:find . | egrep '.\.c$|.\.h$' | xargs cat | sed '/^\s*$/d' | wc -l
— Марк Єронімус

36

Якщо ви хочете використовувати щось інше, ніж скрипт оболонки, спробуйте CLOC :

cloc рахує порожні рядки, рядки коментарів та фізичні рядки вихідного коду багатьма мовами програмування. Він написаний повністю на Perl, без залежностей поза стандартним розподілом Perl v5.6 і вище (код з деяких зовнішніх модулів вбудований в cloc) і тому є досить портативним.


2
Коли я вперше задав це запитання, "cloc" вважав доктрини Python як рядки коду, що було неоптимальним IMHO. Сучасні версії 'cloc' тепер доктрини Python вважають коментарями, що мені подобається набагато більше.
— Джонатан Хартлі

Це правильна відповідь! Я просто спробував завершити роботу, і це добре працює.
— LeeMobile

31

Існує багато способів зробити це, використовуючи загальні утиліти оболонки.

Моє рішення:

grep -cve '^\s*$' <file>

Цей пошук шукає рядки в <file> рядках не збігаються (-v), які відповідають шаблону (-e) '^ \ s * $', що є початком рядка, а потім 0 ​​або більше символів пробілу, а потім до кінця рядка (тобто немає вмісту, окрім пробілів), і відображати кількість відповідних рядків (-c) замість самих відповідних ліній.

Перевага цього методу перед методами, які передбачають підключення wc, полягає в тому, що ви можете вказати кілька файлів і отримати окремий підрахунок для кожного файлу:

$ grep -cve '^\s*$' *.hh

config.hh:36
exceptions.hh:48
layer.hh:52
main.hh:39

2
Дякую! Між іншим, wc забезпечує підрахунок для кожного файлу, плюс загальний.
— Джонатан Хартлі

1
Не, якщо ви все-таки підключаєтесь до нього, як правило, вважається лише одним файлом.
— SpoonMeiser

Це найкраща відповідь на мій погляд.
— simhumileco

-eне потрібно. Це нормальне місце розташування шаблону, і ви нічого з цим не робите. Але нічого поганого в тому, щоб бути явним, якщо це ваш стиль.
— Джектоз

13

'wc' рахує рядки, слова, символи, тому для підрахунку всіх рядків (включаючи порожні) використовується:

wc *.py

Щоб відфільтрувати порожні рядки, ви можете використовувати grep:

grep -v '^\s*$' *.py | wc

'-v' повідомляє grep виводити всі рядки, за винятком тих, що відповідають '^' - це початок рядка '\ s *' - нуль або більше символів пробілу '$' - це кінець рядка * .py - мій приклад для всі файли, які ви хочете порахувати (усі файли python у поточному режимі), виводять трубу на wc. Іди.

Я відповідаю на власне (справжнє) запитання. Не вдалося знайти запис stackoverflow, який охоплював це.


5
\ W - це не збіг для пробілів, він відповідає несловним символам. Це протилежність \ w, символам слова. \ W Відповідатиме будь-чому, що не буквено-цифрове або підкреслення, і тому не буде робити те, що ви тут стверджуєте. Ви маєте на увазі \ s
— SpoonMeiser

9

Ця команда рахує кількість порожніх рядків.
cat fileName | grep -v ^$ | wc -l
Функція регулярного вираження grep -v ^ $ - ігнорування порожніх рядків.


Ця відповідь є найпростішою
— саммбест

2
У catцьому ланцюжку немає необхідності :grep -v ^$ fileName | wl -l
— Еталіди

7
Немає потреби в wc -lтому, що -cgrep -vc ^$ fileName
— греп


5
cat 'filename' | grep '[^ ]' | wc -l

повинен зробити трюк просто чудово


3
Навіщо використовувати cat і передавати файл в grep, коли ви можете передати ім'я файлу в якості аргументу для grep в першу чергу?
— SpoonMeiser

правда, це лише старий псевдонім, який у мене є ... він робить по суті те саме, що і ваше рішення, замість того, щоб використовувати зворотний
— curtisk

4
awk '/^[[:space:]]*$/ {++x} END {print x}' "$testfile"

1
Я би проголосував за це лише тому, що я буквально ніколи не бачив, щоб хто-небудь використовував посилення в сценарії awk, але, на жаль, це враховує лише порожні рядки. :) Ти маєш на увазі awk '!/^[[:space:]]*$/{++x} END{print x}'. Або, якщо ви справді ненавидите негативи awk '{y++} /^[[:space:]]*$/{++x} END{print y-x}',;)
— dannysauer

4
grep -cvE '(^\s*[/*])|(^\s*$)' foo

-c = count
-v = exclude
-E = extended regex
'(comment lines) OR (empty lines)'
where
^    = beginning of the line
\s   = whitespace
*    = any number of previous characters or none
[/*] = either / or *
|    = OR
$    = end of the line

Я розміщую цю заяву, інші варіанти дали мені неправильні відповіді. Це працювало з моїм джерелом Java, де рядки коментарів починаються з / або * (я використовую * у кожному рядку в багаторядковому коментарі).


Це дієве рішення. Єдине, що потрібно помітити: він не враховує багаторядкові коментарі
— Amol

2

Ось сценарій Bash, який рахує рядки коду в проекті. Він реверсивно переходить до вихідного дерева і виключає порожні рядки та коментарі до одного рядка, які використовують "//".

# $excluded is a regex for paths to exclude from line counting
excluded="spec\|node_modules\|README\|lib\|docs\|csv\|XLS\|json\|png"

countLines(){
  # $total is the total lines of code counted
  total=0
  # -mindepth exclues the current directory (".")
  for file in `find . -mindepth 1 -name "*.*" |grep -v "$excluded"`; do
    # First sed: only count lines of code that are not commented with //
    # Second sed: don't count blank lines
    # $numLines is the lines of code
    numLines=`cat $file | sed '/\/\//d' | sed '/^\s*$/d' | wc -l`

    # To exclude only blank lines and count comment lines, uncomment this:
    #numLines=`cat $file | sed '/^\s*$/d' | wc -l`

    total=$(($total + $numLines))
    echo "  " $numLines $file
  done
  echo "  " $total in total
}

echo Source code files:
countLines
echo Unit tests:
cd spec
countLines

Ось як виглядає результат мого проекту :

Source code files:
   2 ./buildDocs.sh
   24 ./countLines.sh
   15 ./css/dashboard.css
   53 ./data/un_population/provenance/preprocess.js
   19 ./index.html
   5 ./server/server.js
   2 ./server/startServer.sh
   24 ./SpecRunner.html
   34 ./src/computeLayout.js
   60 ./src/configDiff.js
   18 ./src/dashboardMirror.js
   37 ./src/dashboardScaffold.js
   14 ./src/data.js
   68 ./src/dummyVis.js
   27 ./src/layout.js
   28 ./src/links.js
   5 ./src/main.js
   52 ./src/processActions.js
   86 ./src/timeline.js
   73 ./src/udc.js
   18 ./src/wire.js
   664 in total
Unit tests:
   230 ./ComputeLayoutSpec.js
   134 ./ConfigDiffSpec.js
   134 ./ProcessActionsSpec.js
   84 ./UDCSpec.js
   149 ./WireSpec.js
   731 in total

Насолоджуйтесь! - Куран


1

Це буде залежати від кількості файлів у проекті. Теоретично ви могли б використовувати

grep -c '.' <list of files>

Де ви можете заповнити список файлів за допомогою утиліти find.

grep -c '.' `find -type f`

Показує кількість рядків на файл.


1
. відповідає пробілу. Це рішення працює лише в тому випадку, якщо ви вважаєте, що рядок, що містить лише пробіл, не порожній, що технічно є, хоча, ймовірно, це не те, що ви шукаєте.
— SpoonMeiser

1

Сценарій рекурсивно підраховує всі непорожні рядки з певним розширенням файлу у поточному каталозі:

#!/usr/bin/env bash
(
echo 0;
for ext in "$@"; do
    for i in $(find . -name "*$ext"); do
        sed '/^\s*$/d' $i | wc -l ## skip blank lines
        #cat $i | wc -l; ## count all lines
        echo +;
    done
done
echo p q;
) | dc;

Використання зразка:

./countlines.sh .py .java .html

Дякуємо перейдіть до @Andy Lester (+1 за ваш коментар) за "непорожню" частину рецепту.
— Кіт Пінсон

Дякуємо також @Michael Cramer (+1 у вашому дописі) за те, що він опублікував (дещо більш багатослівний) "непростий" розчин.
— Кіт Пінсон

1

Якщо ви хочете суму всіх непорожніх рядків для всіх файлів даного розширення файлу протягом проекту:

while read line
do grep -cve '^\s*$' "$line"
done <  <(find $1 -name "*.$2" -print) | awk '{s+=$1} END {print s}'

Перший аргумент - базовий каталог проекту, другий - розширення файлу. Використання зразка:

./scriptname ~/Dropbox/project/src java

Це трохи більше, ніж сукупність попередніх рішень.


Цей отримує нагороду за найбільшу кількість викликів fork + exec, запускаючи grep один раз у рядку у кожному файлі. ;)
— dannysauer

0
grep -v '^\W*$' `find -type f` | grep -c '.' > /path/to/lineCountFile.txt

дає сукупний підрахунок для всіх файлів у поточному каталозі та його підкаталогах.

HTH!


\ W - символи без слів; це не буде відповідати лінії, наприклад ${-[*]} + $@, наприклад. Який, безумовно, дійсний код десь у світі. ;) Ви маєте на увазі \ s для простору.
— dannysauer

0

Це дає підрахунок кількості рядків без підрахунку порожніх рядків:

grep -v ^$ filename wc -l | sed -e 's/ //g' 


-3

Для цього вже існує програма для Linux, яка називається "wc".

Просто

wc -l *.c 

і він дає вам загальні рядки та рядки для кожного файлу.


3
Гей. 'wc' сам по собі не шукає підкаталоги та не відфільтровує порожні рядки, про що явно запитується у запитанні.
— Джонатан Хартлі

wcрахує порожні рядки. ОП хоче рахувати непорожні рядки. Це правда, що він захоче користуватися wc, але лише після редагування потоку з використаннямsed
— EhevuTov
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.