hitung (tidak kosong) baris kode dalam bash


151

Di Bash, bagaimana cara menghitung jumlah baris kode yang tidak kosong dalam suatu proyek?


1
Banyak solusi di bawah ini hanya berfungsi untuk satu file (misalnya foo.c). Adakah pemikiran tentang jumlah baris toal dalam suatu proyek (misalnya banyak file dalam struktur direktori, dan tidak termasuk file biner)?
troubleshootingPuzzles

5
@solvingPuzzles Saya rasa saya bisa menjawab bagian itu. Untuk solusi apa pun yang bekerja pada satu file, misalnya "cat FILE | sed blah", Anda dapat bekerja pada banyak file dengan mengganti "cat FILE" dengan perintah yang mencantumkan nama file untuk beroperasi, misalnya "find. -Name '* .py '", dan pipa itu menjadi" xargs cat ". mis. "find. -name '* .py' | xargs cat | sed '/ ^ \ s * $ / d' | wc -l"
Jonathan Hartley

2
@JonathanHartley @solvingPuzzles ada juga program seperti slocdan clocyang ada di sini untuk menghitung jumlah baris kode tersebut.
AsTeR

OP di sini: Ketika saya pertama kali menanyakan masalah ini, 'cloc' tidak melakukan pekerjaan yang sangat baik pada kode Python. Sekarang ini luar biasa.
Jonathan Hartley

cloc juga tersedia sebagai modul npm dan menghemat banyak waktu.
Krishna Vedula

Jawaban:


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

Dan jika Anda menganggap komentar sebagai baris kosong:

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

Meskipun, itu tergantung pada bahasa.


24
Tidak yakin mengapa Anda menggunakan kucing di sana. Gunakan foo.c atau foo.pl sebagai nama file untuk diteruskan ke sed. sed '/ ^ \ s * $ / d' foo.c | wc -l
Andy Lester

28
Hanya kebiasaan. Saya membaca pipa dari kiri ke kanan, yang berarti saya biasanya mulai dengan kucing, lalu beraksi, beraksi, beraksi, dll. Jelas, hasil akhirnya sama.
Michael Cramer

32
Untuk melakukan ini untuk semua file di semua subfolder dan untuk mengecualikan komentar dengan '//', perluas perintah ini ke ini: find. -type f -name '* .c' -exec cat {} \; | sed '/ ^ \ s * # / d; / ^ \ s * $ / d; / ^ \ s * \ / \ // d' | wc-l
Benjamin Intal

11
Anda dapat dibaca dari kiri ke kanan tanpa UUOC: < foo.pl sed 'stuff' | wc -l.
jw013

22
Secara umum, UUOC tidak penting, tetapi mudah dibaca.
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

Di atas akan memberi Anda jumlah total baris kode (baris kosong dihapus) untuk proyek (folder saat ini dan semua subfolder secara rekursif).

Dalam "./blog" "./punbb" "./js/3rdparty" dan "./pma" di atas adalah folder yang saya daftar hitam karena saya tidak menulis kode di dalamnya. Juga .php, .as, .sql, .css, .js adalah ekstensi dari file yang sedang dilihat. File dengan ekstensi berbeda diabaikan.


1
variasi untuk aplikasi Rails: find. -path './log' -prune -o -path './trunk' -prune -o -path './branches' -prune -o -path './vendor' -prune -o -path './tmp '-prune -o -print | egrep '\ .rb | \ .erb | \ .css | \ .js | \ .yml' | grep -v 'svn' | xargs cat | sed '/ ^ \ s * $ / d' | wc-l
poseid

1
Anda perlu menambahkan a $ke grep ( ...\.js$|...) jika tidak akan cocok feature.js.swp.
Xeoncross

Anda lupa jangkar, jadi itu termasuk file yang salah. Dan versi yang lebih sederhana dengan penahan:find . | egrep '.\.c$|.\.h$' | xargs cat | sed '/^\s*$/d' | wc -l
Mark Jeronimus

36

Jika Anda ingin menggunakan sesuatu selain skrip shell, coba CLOC :

cloc menghitung baris kosong, baris komentar, dan garis fisik kode sumber dalam banyak bahasa pemrograman. Ini ditulis seluruhnya dalam Perl tanpa ketergantungan di luar distribusi standar Perl v5.6 dan lebih tinggi (kode dari beberapa modul eksternal tertanam di dalam cloc) dan sangat portabel.


2
Ketika saya pertama kali mengajukan pertanyaan ini, 'cloc' menghitung dokumen Python sebagai baris kode, yang merupakan IMHO suboptimal. Versi modern 'cloc' sekarang menghitung dokumen Python sebagai komentar, yang sangat saya sukai.
Jonathan Hartley

Ini jawaban yang benar! Saya baru saja mencoba mencari dan berhasil dengan baik.
LeeMobile

31

Ada banyak cara untuk melakukan ini, menggunakan utilitas shell umum.

Solusi saya adalah:

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

Ini mencari baris dalam <file> baris tidak cocok (-v) yang cocok dengan pola (-e) '^ \ s * $', yang merupakan awal dari sebuah baris, diikuti oleh 0 atau lebih karakter spasi, diikuti pada akhir baris (mis. tidak ada konten selain spasi putih), dan tampilkan hitungan baris yang cocok (-c) alih-alih baris yang cocok itu sendiri.

Keuntungan dari metode ini dibandingkan metode yang melibatkan pemipaan wc, adalah Anda dapat menentukan beberapa file dan mendapatkan hitungan terpisah untuk setiap file:

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

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

2
Terima kasih! Kebetulan, wc memang menyediakan hitungan untuk setiap file yang diberikan, ditambah total.
Jonathan Hartley

1
Tidak jika Anda mem-pipkannya, standar dalam jumlah hanya satu file.
SpoonMeiser

Ini jawaban terbaik menurut saya.
simhumileco

-etidak perlu. Itulah lokasi posisi normal dari pola dan Anda tidak melakukan apa pun yang funky dengannya. Tetapi tidak ada yang salah dengan menjadi eksplisit, jika itu gaya Anda.
Jacktose

13

'wc' menghitung baris, kata, karakter, jadi untuk menghitung semua baris (termasuk yang kosong) gunakan:

wc *.py

Untuk menyaring baris kosong, Anda dapat menggunakan grep:

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

'-v' memberitahu grep untuk menampilkan semua baris kecuali yang cocok dengan '^' adalah awal dari sebuah baris '\ s *' adalah nol atau lebih karakter spasi putih '$' adalah akhir dari baris * .py adalah contoh saya untuk semua file yang ingin Anda hitung (semua file python dalam direktori saat ini) menampilkan output pipa ke wc. Pergilah.

Saya menjawab pertanyaan saya sendiri (asli). Tidak dapat menemukan entri stackoverflow yang membahas hal ini.


5
\ W bukan kecocokan untuk spasi putih, itu cocok dengan karakter non-kata. Ini kebalikan dari \ w, karakter kata. \ W Akan cocok dengan apa pun yang bukan alfanumerik atau garis bawah, dan karena itu tidak akan melakukan apa yang Anda klaim di sini. Maksud Anda
SpoonMeiser

9

Perintah ini menghitung jumlah baris yang tidak kosong.
cat fileName | grep -v ^$ | wc -l
grep -v ^ $ fungsi ekspresi reguler mengabaikan baris kosong.


Jawaban ini adalah yang paling mudah
samthebest

2
Tidak perlu catdalam rantai ini:grep -v ^$ fileName | wl -l
Aethalides

7
Juga tidak perlu wc -lkarena grep memiliki -c:grep -vc ^$ fileName
Jacktose


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

harus melakukan trik dengan baik


3
Mengapa menggunakan cat dan pipa file ke grep, ketika Anda bisa memberikan nama file sebagai argumen untuk grep?
SpoonMeiser

benar, ini hanya alias lama yang saya miliki ... itu pada dasarnya sama dengan solusi Anda alih-alih menggunakan invers
curtisk

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

1
Saya memilih ini hanya karena saya benar-benar tidak pernah melihat orang menggunakan preincrement dalam skrip awk, tapi sayangnya ini hanya menghitung baris kosong. :) Maksud Anda awk '!/^[[:space:]]*$/{++x} END{print x}'. Atau, jika Anda benar-benar membenci negatif awk '{y++} /^[[:space:]]*$/{++x} END{print y-x}'
,;

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

Saya memposting ini karena pilihan lain memberikan jawaban yang salah bagi saya. Ini bekerja dengan sumber java saya, di mana baris komentar mulai dengan / atau * (saya menggunakan * pada setiap baris dalam komentar multi-baris).


Ini adalah solusi yang bisa diterapkan. Satu-satunya hal yang perlu diperhatikan: tidak menghitung komentar multi-baris
Amol

2

Berikut skrip Bash yang menghitung baris kode dalam suatu proyek. Itu melintasi pohon sumber secara rekursif, dan mengecualikan baris kosong dan komentar baris tunggal yang menggunakan "//".

# $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

Seperti apa hasilnya untuk proyek saya :

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

Nikmati! - Curran


1

Agak akan tergantung pada jumlah file yang Anda miliki di proyek. Secara teori Anda bisa menggunakan

grep -c '.' <list of files>

Di mana Anda dapat mengisi daftar file dengan menggunakan utilitas temukan.

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

Akan memberi Anda jumlah baris per file.


1
. cocok dengan spasi putih. Solusi ini hanya berfungsi jika Anda menganggap garis yang hanya berisi spasi kosong sebagai non-kosong, yang secara teknis, meskipun mungkin bukan yang Anda cari.
SpoonMeiser

1

Script untuk menghitung secara rekursif semua baris non-kosong dengan ekstensi file tertentu di direktori saat ini:

#!/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;

Penggunaan sampel:

./countlines.sh .py .java .html

Terima kasih ke @Andy Lester (+1 di komentar Anda) untuk bagian "tidak kosong" dari resep.
Keith Pinson

Terima kasih juga kepada @Michael Cramer (memberi +1 pada posting Anda) untuk awalnya memposting solusi "tidak kosong" (sedikit lebih bertele-tele).
Keith Pinson

1

Jika Anda ingin jumlah semua baris yang tidak kosong untuk semua file dari ekstensi file yang diberikan di seluruh proyek:

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

Arg pertama adalah direktori basis proyek, kedua adalah ekstensi file. Penggunaan sampel:

./scriptname ~/Dropbox/project/src java

Ini sedikit lebih dari kumpulan solusi sebelumnya.


Yang ini mendapat penghargaan untuk jumlah terbesar dari panggilan fork + exec dengan meluncurkan grep sekali per baris di setiap file. ;)
dannysauer

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

memberikan jumlah agregat untuk semua file di direktori saat ini dan subdirektori.

HTH!


\ W adalah karakter non-kata; ini tidak akan cocok dengan garis seperti ${-[*]} + $@, misalnya. Yang pasti kode yang valid di suatu tempat di dunia. ;) Maksud Anda untuk ruang.
dannysauer

0

Ini memberikan hitungan jumlah garis tanpa menghitung baris kosong:

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

0
rgrep . | wc -l

memberikan jumlah baris tidak kosong dalam direktori kerja saat ini.


-3

Sudah ada program untuk ini di linux yang disebut 'wc'.

Hanya

wc -l *.c 

dan itu memberi Anda total baris dan baris untuk setiap file.


3
Hei. 'wc' dengan sendirinya tidak mencari subdir, dan tidak menyaring baris kosong, keduanya secara eksplisit diminta dalam pertanyaan.
Jonathan Hartley

wcmenghitung garis kosong. OP ingin menghitung garis yang tidak kosong. Memang benar dia akan ingin menggunakan wc, tetapi hanya setelah itu telah diedit menggunakan menggunakansed
EhevuTov
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.