(गैर-रिक्त) लाइनों को-कोड को बैश में गिनें


151

बैश में, मैं एक परियोजना में कोड की गैर-रिक्त लाइनों की संख्या कैसे गिनूं?


1
नीचे दिए गए बहुत सारे समाधान केवल एक फ़ाइल (जैसे foo.c) के लिए काम करते हैं । एक परियोजना में लाइनों की टोल संख्या के बारे में कोई विचार (जैसे कि निर्देशिका संरचना में कई फाइलें, और बाइनरी फाइलें छोड़कर)?
सॉल्विंगपीसूट्स

5
मुझे लगता है कि मैं उस हिस्से का जवाब दे सकता हूं। एक फ़ाइल पर काम करने वाले किसी भी समाधान के लिए, उदाहरण के लिए "cat FILE | sed blah", आप "cat FILE" को एक कमांड के साथ बदलकर कई फाइलों पर काम कर सकते हैं, जो फ़ाइल नाम को संचालित करने के लिए सूचीबद्ध करता है, जैसे "find -name '*। .py '', और "xargs cat" में पाइप करें। उदाहरण के लिए "ढूंढें। -name '* .py' | xargs cat | sed '/ ^ \ s * $ / d' | wc -l"
जोनाथन हार्टले

2
@JonathanHartley @solvePatalog ऐसे प्रोग्राम भी हैं जैसे slocऔर clocउन कोड लाइनों को करने के लिए यहां हैं।
एएसटीआरआर

यहाँ ओपी: जब मैंने पहली बार यह समस्या पूछी, तो 'क्लॉक' ने पायथन कोड पर बहुत अच्छा काम नहीं किया। आजकल यह बहुत अच्छा है।
जोनाथन हार्टले

क्लॉक एक एनपीएम मॉड्यूल के रूप में भी उपलब्ध है और बहुत समय बचाता है।
कृष्ण वेदूला

जवाबों:


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

और यदि आप टिप्पणियों को रिक्त रेखा मानते हैं:

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

हालाँकि, यह भाषा पर निर्भर है।


24
यकीन नहीं होता कि आप वहां बिल्ली का उपयोग क्यों कर रहे हैं। Sed को पास करने के लिए फ़ाइल नाम के रूप में foo.c या foo.pl का उपयोग करें। sed '/ ^ \ s * $ / d' foo.c | wc -l
एंडी लेस्टर

28
बस आदत है। मैं बाएं से दाएं पाइपलाइनों को पढ़ता हूं, जिसका अर्थ है कि मैं आमतौर पर बिल्ली से शुरू करता हूं, फिर कार्रवाई, कार्रवाई, कार्रवाई आदि। स्पष्ट रूप से, अंतिम परिणाम समान है।
माइकल क्रैमर

32
सभी सबफ़ोल्डर्स में सभी फ़ाइलों के लिए ऐसा करने के लिए और '//' के साथ टिप्पणियों को बाहर करने के लिए, इस कमांड को इस में विस्तारित करें: खोजें। -Type f -name '* .c' -exec cat {} \; | sed '/ ^ \ s * # / d; / ^ \ s * $ / d; / ^ \ s * \ / \ / d' | wc -l
बेंजामिन इन्टल

11
आप यूयूओसी के बिना बाएं से दाएं पढ़ सकते हैं < foo.pl sed 'stuff' | wc -l:।
jw013

22
सामान्यतया, यूयूओसी महत्वपूर्ण नहीं है, लेकिन पठनीयता है।
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 "" ./s/3rdparty "और" ./pma "फ़ोल्डर हैं I ब्लैकलिस्ट करें क्योंकि मैंने उनमें कोड नहीं लिखा था। इसके अलावा .php, .as, .sql, .css, .js उन फाइलों के एक्सटेंशन हैं जिन्हें देखा जा रहा है। एक अलग एक्सटेंशन वाली किसी भी फाइल को अनदेखा कर दिया जाता है।


1
रेल एप्लिकेशन के लिए भिन्नता: खोजें। -path './log' -prune -o -path './trunk' -prune -o -path './branches' -prune -o -path './vendor' -prune -o -path'/tmp '-प्रो-लो-छाप | उदा। ' grep -v 'svn' | xargs बिल्ली | 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 आज़माएँ :

क्लोक कई प्रोग्रामिंग भाषाओं में रिक्त लाइनों, टिप्पणी लाइनों और स्रोत कोड की भौतिक रेखाओं को गिनता है। यह पूरी तरह से पर्ल में पूरी तरह से पर्ल वी 5.6 के मानक वितरण के बाहर निर्भरता के साथ लिखा गया है और उच्चतर (कुछ बाहरी मॉड्यूल से कोड क्लॉक के भीतर एम्बेडेड है) और इसलिए काफी पोर्टेबल है।


2
जब मैंने पहली बार यह सवाल पूछा था, तो 'क्लॉक' ने पायथन डॉकस्ट्रिंग्स को कोड की पंक्तियों के रूप में गिना था, जो कि आईएमटीएचओ था। 'क्लॉक' के आधुनिक संस्करण अब पायथन डॉकस्ट्रिंग्स को टिप्पणियों के रूप में गिनते हैं, जो मुझे बहुत पसंद हैं।
जोनाथन हार्टले

यह सही जवाब है! मैंने सिर्फ क्लॉक आउट करने की कोशिश की है और यह अच्छी तरह से काम करता है।
लीमोबाइल

31

सामान्य शेल उपयोगिताओं का उपयोग करते हुए, ऐसा करने के कई तरीके हैं।

मेरा समाधान है:

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

यह <फ़ाइल> लाइनों से मेल नहीं खाता (-v) रेखाएँ जो प्रतिमान (-e) '^ \ _ * $' से मेल खाती हैं, जो एक पंक्ति की शुरुआत है, जिसके बाद 0 या अधिक व्हाट्सएप वर्ण हैं, उसके बाद एक पंक्ति के अंत तक (अर्थात। कोई सामग्री तब व्हॉट्सएप नहीं), और मिलान लाइनों के बजाय मिलान लाइनों (-c) की एक गिनती प्रदर्शित करें।

इस पद्धति का एक तरीका है जिसमें पाइपिंग को शामिल करना शामिल है wc, यह है कि आप कई फ़ाइलों को निर्दिष्ट कर सकते हैं और प्रत्येक फ़ाइल के लिए एक अलग गणना प्राप्त कर सकते हैं:

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

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

2
धन्यवाद! संयोग से, wc प्रत्येक दी गई फ़ाइल के लिए एक गणना प्रदान करता है, साथ ही कुल।
जोनाथन हार्टले

1
नहीं अगर आप इसे में पाइप कर रहे हैं, मानक के रूप में सिर्फ एक फ़ाइल के रूप में मायने रखता है।
स्पूनमाइज़र

मेरी राय में यह सबसे अच्छा जवाब है।
सिम्हुमेलेको

-eइसकी आवश्यकता नही है। यह पैटर्न की सामान्य स्थिति है और आप इसके साथ कुछ भी मजेदार नहीं कर रहे हैं। लेकिन स्पष्ट होने में कुछ भी गलत नहीं है, अगर वह आपकी शैली है।
जैकटोज़

13

'wc' लाइनों, शब्दों, वर्णों को गिनता है, इसलिए सभी रेखाओं (रिक्त वाले सहित) का उपयोग करने के लिए गणना करें:

wc *.py

रिक्त लाइनों को फ़िल्टर करने के लिए, आप grep का उपयोग कर सकते हैं:

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

'-v' उन सभी रेखाओं को आउटपुट करने के लिए grep को बताता है, जो उस मैच को छोड़कर '^' एक लाइन की शुरुआत है '\ _ *' शून्य है या अधिक व्हाट्सएप वर्ण '$' एक पंक्ति का अंत है * .py मेरे लिए उदाहरण है। सभी फाइलें जिन्हें आप गिनना चाहते हैं (मौजूदा dir में सभी अजगर फाइलें) wc को पाइप आउटपुट। तुम जाओ।

मैं अपने स्वयं के (वास्तविक) प्रश्न का उत्तर दे रहा हूं। स्टैकओवरफ़्लो प्रविष्टि नहीं मिली जो इसे कवर करती है।


5
व्हॉट्सएप के लिए एक मैच नहीं है, यह गैर-शब्द वर्णों से मेल खाता है। यह \ w, शब्द वर्णों के विपरीत है। \ W कुछ भी मेल खाता है जो अल्फ़ान्यूमेरिक या अंडरस्कोर नहीं है, और इसलिए वह नहीं करेगा जो आप यहाँ दावा करते हैं। तुम्हारा मतलब है \ s
SpoonMeiser

9

यह आदेश गैर-रिक्त लाइनों की संख्या की गणना करता है।
cat fileName | grep -v ^$ | wc -l
grep -v ^ $ रेगुलर एक्सप्रेशन फंक्शन, ब्लैंक लाइन्स को अनदेखा कर रहा है।


यह उत्तर सबसे सीधा है
samthebest

2
catइस श्रृंखला की कोई आवश्यकता नहीं है :grep -v ^$ fileName | wl -l
Aethalides

7
वहाँ भी कोई जरूरत नहीं है wc -lक्योंकि grep है -c:grep -vc ^$ fileName
जैकटोज़


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

चाल ठीक करना चाहिए


3
बिल्ली का उपयोग क्यों करें और फ़ाइल को grep में पाइप करें, जब आप फ़ाइल नाम को पहली जगह में grep करने के तर्क के रूप में पास कर सकते हैं?
स्पूनमाइजर

सच है, यह सिर्फ मेरे पास एक पुराना उर्फ ​​है ... यह अनिवार्य रूप से उलटा उपयोग करने के बजाय आपके समाधान के समान है
curtisk

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

1
मैं इसे सिर्फ इसलिए वोट करूंगा क्योंकि मैंने सचमुच में किसी को भी एक स्क्रिप्ट में प्रीइन्क्रिमेंट का उपयोग करते हुए नहीं देखा है, लेकिन दुर्भाग्य से यह केवल खाली लाइनों को गिनता है। :) आपका मतलब है 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

मैं इस कारण पोस्ट करता हूं अन्य विकल्पों ने मेरे लिए गलत उत्तर दिए हैं। यह मेरे जावा स्रोत के साथ काम करता है, जहां टिप्पणी लाइनें / या * (मैं बहु-पंक्ति टिप्पणी में प्रत्येक पंक्ति पर * का उपयोग करता है) के साथ शुरू होता है।


यह एक व्यावहारिक समाधान है। केवल ध्यान देने योग्य बात: यह बहु पंक्ति टिप्पणियों
अमोल

2

यहाँ एक बैश स्क्रिप्ट है जो किसी प्रोजेक्ट में कोड की पंक्तियों को गिनता है। यह एक स्रोत के पेड़ को पुनरावृत्ति करता है, और यह रिक्त पंक्तियों और एकल पंक्ति टिप्पणियों को बाहर करता है जो "//" का उपयोग करते हैं।

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

जहां आप फाइंड यूटिलिटी का उपयोग करके फाइलों की सूची भर सकते हैं।

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

आपको प्रति फ़ाइल एक लाइन काउंट देगा।


1
। व्हॉट्सएप से मेल खाता है। यह समाधान केवल तभी काम करता है जब आप केवल व्हॉट्सएप वाली एक पंक्ति को गैर-रिक्त मानते हैं, जो कि यह तकनीकी रूप से है, हालांकि यह संभवतः वह नहीं है जो आप के बाद हैं।
स्पूनमाइज़र

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}'

पहला arg प्रोजेक्ट का बेस डायरेक्टरी है, दूसरा फाइल एक्सटेंशन है। नमूना उपयोग:

./scriptname ~/Dropbox/project/src java

यह पिछले समाधानों के संग्रह से थोड़ा अधिक है।


यह प्रत्येक फ़ाइल में प्रति पंक्ति एक बार grep लॉन्च करके सबसे बड़ी संख्या में कांटा + निष्पादन कॉल के लिए पुरस्कार प्राप्त करता है। ;)
dannysauer

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

वर्तमान निर्देशिका और इसके उपनिर्देशिकाओं में सभी फाइलों के लिए एक समग्र गणना देता है।

HTH!


\ W गैर-शब्द वर्ण है; ${-[*]} + $@उदाहरण के लिए, यह रेखा से मेल नहीं खाता है । जो निश्चित रूप से दुनिया में कहीं वैध कोड है। ;) आप अंतरिक्ष के लिए मतलब है।
dannysauer

0

यह खाली लाइनों की गिनती के बिना लाइनों की संख्या की गिनती देता है:

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


-3

'Wc' नामक लाइनक्स पर इसके लिए पहले से ही एक कार्यक्रम है।

केवल

wc -l *.c 

और यह आपको कुल पंक्तियाँ और प्रत्येक फ़ाइल के लिए लाइनें देता है।


3
अरे। 'wc' अपने आप में उपखंडों को नहीं खोजता है, और यह खाली लाइनों को फ़िल्टर नहीं करता है, दोनों ने स्पष्ट रूप से प्रश्न के लिए पूछा है।
जोनाथन हार्टले

wcखाली लाइनों की गिनती करता है। ओपी गैर-रिक्त लाइनों की गिनती करना चाहता है। यह सच है कि वह उपयोग करना चाहेगा wc, लेकिन इसका उपयोग करने के बाद ही इसे संपादित किया गयाsed
EhevuTov
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.