bash içinde kod satırları (boş olmayan)


151

Bash'te, bir projedeki boş olmayan kod satırlarının sayısını nasıl hesaplayabilirim?


1
Aşağıdaki çözümlerin birçoğu sadece bir dosya için çalışır (örneğin foo.c). Projedeki satır sayısı hakkında herhangi bir düşünce (örneğin, dizin yapısındaki birçok dosya ve ikili dosyalar hariç)?
solvingPuzzles

5
@solvingPuzzles Sanırım bu bölüme cevap verebilirim. Bir dosya üzerinde çalışan herhangi bir çözüm için, örneğin "cat FILE | sed blah", "cat FILE" yerine çalışacak dosya adlarını listeleyen bir komutla değiştirerek birçok dosya üzerinde çalışabilirsiniz, örneğin "find. -Name '* .py '"ve" xargs cat "a ekleyin. örneğin "find. -name '* .py' | xargs cat | sed '/ ^ \ s * $ / d' | wc -l"
Jonathan Hartley

2
Bulmacalar gibi programlar da var slocve clocbu kod satırlarını yapmak için burada.
AsTeR

OP burada: Bu soruyu ilk sorduğumda, 'cloc' Python kodunda çok iyi bir iş yapmadı. Bugünlerde harika.
Jonathan Hartley

cloc ayrıca bir npm modülü olarak da mevcuttur ve çok zaman kazandırır.
Krishna Vedula

Yanıtlar:


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

Ve yorumları boş satırlar olarak görürseniz:

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

Yine de, bu dile bağlıdır.


24
Orada kediyi neden kullandığınızdan emin değilim. Sed'e geçmek için dosya adı olarak foo.c veya foo.pl kullanın. sed '/ ^ \ s * $ / d' foo.c | wc -l
Andy Lester

28
Sadece alışkanlık. Boru hatlarını soldan sağa okudum, bu da genellikle kedi, sonra aksiyon, aksiyon, aksiyon vb. İle başladığım anlamına gelir.
Michael Cramer

32
Bunu tüm alt klasörlerdeki tüm dosyalar için yapmak ve '//' ile yorumları hariç tutmak için bu komutu şu şekilde genişletin: find. -tip f -adı '* .c' -exec cat {} \; | sed '/ ^ \ s * # / d; / ^ \ s * $ / d; / ^ \ s * \ / \ // d' | wc -l
Benjamin Intal

11
Sen UUOC olmadan soldan sağa okuyabilirsiniz: < foo.pl sed 'stuff' | wc -l.
jw013

22
Genel olarak, UUOC önemli değildir, ancak okunabilirlik önemlidir.
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

Yukarıdakiler, bir proje için (mevcut klasör ve tüm alt klasörler özyinelemeli) toplam kod satırı sayısını (boş satırlar kaldırıldı) verecektir.

Yukarıdaki "./blog" "./punbb" "./js/3rdparty" ve "./pma" içinde, kodu yazmadığım için kara listeye aldığım klasörler. Ayrıca .php, .as, .sql, .css, .js bakılan dosyaların uzantılarıdır. Farklı bir uzantıya sahip dosyalar yok sayılır.


1
Rails uygulaması için varyasyon: bulun. -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 kedi | sed '/ ^ \ s * $ / d' | wc -l
poseid

1
$Grep ( ...\.js$|...) öğesine a eklemeniz gerekir, aksi takdirde eşleşir feature.js.swp.
Xeoncross

Sabitlemeyi unuttunuz, bu yüzden yanlış dosyalar içeriyor. Ve demirlemeyle daha da basit bir versiyon:find . | egrep '.\.c$|.\.h$' | xargs cat | sed '/^\s*$/d' | wc -l
Mark Jeronimus

36

Kabuk betiğinden başka bir şey kullanmak istiyorsanız, CLOC'yi deneyin :

cloc birçok programlama dilinde boş satırları, yorum satırlarını ve kaynak kodun fiziksel satırlarını sayar. Tamamen Perl'de yazılmıştır ve Perl v5.6 ve daha yüksek standart dağılım dışında hiçbir bağımlılık yoktur (bazı harici modüllerden kodlar cloc içine gömülmüştür) ve bu nedenle oldukça taşınabilir.


2
Bu soruyu ilk sorduğumda, 'cloc' Python öğretilerini kod satırları olarak saydı ki bu da IMHO'yu yetersizdi. Modern 'cloc' versiyonları artık Python docstrings'i yorum olarak sayıyor.
Jonathan Hartley

Bu doğru cevap! Sadece cloc'u denedim ve işi iyi yapıyor.
LeeMobile

31

Ortak kabuk yardımcı programlarını kullanarak bunu yapmanın birçok yolu vardır.

Benim çözümüm:

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

Bu, <dosya> satırındaki satırın eşleşmesi (-e) '^ \ s * $' ile eşleşen satırları arar, bu satırın başlangıcıdır, ardından 0 veya daha fazla boşluk karakteri gelir. satır sonuna kadar (yani boşluktan başka içerik yok) ve eşleşen satırların kendileri yerine eşleşen satır sayısını (-c) görüntüler.

Bu yöntemin içine boru ekleme yöntemlerine göre bir avantajı, wcbirden çok dosya belirleyebilmeniz ve her dosya için ayrı bir sayı alabilmenizdir:

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

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

2
Teşekkürler! Bu arada, wc verilen her dosya için bir sayım ve bir toplam sağlar.
Jonathan Hartley

1
Buna rağmen, standart olarak sadece bir dosya olarak sayılırsanız değil.
SpoonMeiser

Bence en iyi cevap bu.
simhumileco

-egerekli değil. Desenin normal konumsal konumu ve onunla korkak bir şey yapmıyorsunuz. Ama açık olmanın yanlış bir yanı yok, eğer tarzınız buysa.
Jacktose

13

'wc' satırları, kelimeleri, karakterleri sayar, böylece tüm satırları (boş olanlar dahil) saymak için şunu kullanın:

wc *.py

Boş satırları filtrelemek için grep kullanabilirsiniz:

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

'-v', grep'e '^' ile eşleşen satırlar dışındaki tüm satırların çıktısını vermesini söyler '\ s *' sıfır veya daha fazla boşluk karakteri '$' bir satırın sonu * .py benim örneğim saymak istediğiniz tüm dosyalar (geçerli dir içindeki tüm python dosyaları) wc. Defol git.

Kendi (gerçek) soruma cevap veriyorum. Bunu kapsayan bir yığın akışı girdisi bulunamadı.


5
\ W boşlukla eşleşmez, sözcük olmayan karakterlerle eşleşir. \ W, kelime karakterlerinin tam tersi. \ W Alfasayısal veya alt çizgi olmayan herhangi bir şeyle eşleşir ve bu nedenle burada iddia ettiklerini yapmaz. Yani s
SpoonMeiser

9

Bu komut boş olmayan satır sayısını sayar.
cat fileName | grep -v ^$ | wc -l
grep -v ^ $ normal ifade işlevi boş satırları yoksayar.


Bu cevap en basit
olanıdır

2
catBu zincirde gerek yok :grep -v ^$ fileName | wl -l
Aethalides

7
Ayrıca, wc -l-cgrep -vc ^$ fileName
grep'in


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

hile yapmalı iyi


3
Dosya adını ilk başta grep'e argüman olarak aktarabildiğinizde neden cat ve file dosyasını grep'e yönlendirin?
SpoonMeiser

doğru, sadece eski bir takma ad var ... tersini kullanmak yerine çözümünüzle aynı şeyi yapıyor
curtisk 22:08

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

1
Tam anlamıyla hiç kimsenin bir awk senaryosunda preincrement kullandığını görmediğim için oy verdim, ancak maalesef bu sadece boş satırları sayar. :) Demek istiyorsun awk '!/^[[:space:]]*$/{++x} END{print x}'. Veya, negatiflerden gerçekten nefret ederseniz 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

Bu becaus sonrası diğer seçenekler benim için yanlış cevaplar verdi. Bu, yorum satırlarının / veya * ile başladığı java kaynağımla çalıştı (çok satırlı yorumdaki her satırda * kullanıyorum).


Bu uygulanabilir bir çözümdür. Dikkat edilmesi gereken tek şey: çok satırlı yorumlar sayılmaz
Amol

2

İşte bir projedeki kod satırlarını sayan bir Bash betiği. Kaynak ağacını özyinelemeli olarak gezer ve "//" kullanan boş satırları ve tek satırlık yorumları hariç tutar.

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

İşte çıkış için şu şekilde görünür projemde :

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

Zevk almak! - Curran


1

Bu, projenizdeki dosya sayısına bağlı olacaktır. Teorik olarak kullanabilirsiniz

grep -c '.' <list of files>

Nerede find yardımcı programını kullanarak dosya listesini doldurabilirsiniz.

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

Dosya başına satır sayısı verir.


1
. boşlukla eşleşir. Bu çözüm, yalnızca boşluk içeren bir satırın boş olmadığını düşündüğünüzde işe yarar.
SpoonMeiser

1

Geçerli dizinde belirli bir dosya uzantısına sahip boş olmayan tüm satırları yinelemeli olarak sayacak komut dosyası:

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

Örnek kullanım:

./countlines.sh .py .java .html

Tarifin "boş olmayan" kısmı için @Andy Lester'a (yorumunuzda +1) gidin.
Keith Pinson

Ayrıca @Michael Cramer'a (yayınınızda +1) orijinal olarak (biraz daha ayrıntılı) "boş olmayan" çözümü gönderdiğiniz için teşekkür ederiz.
Keith Pinson

1

Bir proje boyunca belirli bir dosya uzantısının tüm dosyaları için boş olmayan tüm satırların toplamını istiyorsanız:

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

İlk argüman projenin temel dizinidir, ikincisi dosya uzantısıdır. Örnek kullanım:

./scriptname ~/Dropbox/project/src java

Önceki çözümlerden oluşan bir koleksiyondan biraz daha fazlası.


Bu, her dosyada hat başına bir kez grep başlatarak en çok fork + exec çağrısı ödülünü alır. ;)
dannysauer

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

geçerli dizindeki ve alt dizinlerindeki tüm dosyalar için bir toplam sayı verir.

HTH!


\ W sözcük olmayan karakterlerdir; bu, ${-[*]} + $@örneğin bir çizgiyle eşleşmez . Bu kesinlikle dünyanın herhangi bir yerinde geçerli bir koddur. ;) Uzay için demek istediniz.
dannysauer

0

Bu, boş satırları saymadan satır sayısını verir:

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

0
rgrep . | wc -l

geçerli çalışma dizinindeki boş olmayan satırların sayısını verir.


-3

Bunun için linux'da 'wc' adı verilen bir program var.

Sadece

wc -l *.c 

ve her dosya için toplam satırları ve satırları verir.


3
Hey. 'wc' tek başına alt dizinleri aramaz ve her ikisi de açıkça sorulan boş satırları filtrelemez.
Jonathan Hartley

wcboş satırları sayar. OP, boş olmayan satırları saymak istiyor. Kullanmak isteyeceği doğrudur wc, ancak yalnızca akış kullanılarak düzenlendikten sonrased
EhevuTov
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.