मैं एक फाइल में लाइनों पर संख्याओं को कैसे जोड़ सकता हूं


24

मेरे पास एक फाइल है जो इस प्रकार है:

1
3
4
1
4
3
1
2

मैं इसका कुल (यानी 1 + 3 + 4 + 1 + 4 + 3 + 1 + 2 = 19) कैसे पा सकता हूँ?


1
संदर्भ के लिए, मैं स्टैक एक्सचेंज एपीआई से आस्क उबंटू पर लगाए गए बैज की संख्या गिन रहा हूं।
टिम

के साथcat badges.json | grep -o '"award_count":[0-9],"rank":"gold"' | grep -o [0-9]
टिम

हालांकि मुझे अब एहसास हुआ कि एपीआई के पास एक badge_countतरीका है।
टिम

यदि आप एपीआई से बैज की गिनती कर रहे हैं, तो एपीआई का उपयोग करने के लिए आप जिस भाषा का उपयोग कर रहे हैं, वह ऐसा नहीं कर सकती (अजगर, जावास्क्रिप्ट)?
Braiam

जवाबों:


42

bcविभाजक के रूप pasteमें एक एकल में लाइनों को प्राप्त करने के लिए थोड़ी मदद से +:

paste -sd+ file.txt | bc

grepएक स्थिर फ़ाइल के बजाय (या किसी अन्य कमांड) के आउटपुट का उपयोग करने के लिए, इसके grepSTDOUT में से पास करें paste:

grep .... | paste -sd+ | bc

उदाहरण:

% cat file.txt            
1
3
4
1
4
3
1
2

% paste -sd+ file.txt | bc
19

% grep . file.txt | paste -sd+ | bc
19

यदि आपको उपयोग करना चाहिए bash, तो आप फ़ाइल सामग्री को सहेजने के लिए एक सरणी का उपयोग कर सकते हैं और फिर तत्वों पर पुनरावृति कर सकते हैं या आप फ़ाइल लाइन को लाइन से पढ़ सकते हैं और प्रत्येक पंक्ति के लिए योग कर सकते हैं, दूसरा दृष्टिकोण अधिक कुशल होगा:

$ time { nums=$(<file.txt); for i in ${nums[@]}; do (( sum+=i )); done; echo $sum ;}
19

real    0m0.002s
user    0m0.000s
sys 0m0.000s

$ time { while read i; do (( sum+=i )); done <file.txt; echo $sum ;}
19

real    0m0.000s
user    0m0.000s
sys 0m0.000s

अच्छा। प्रश्न को बदलने के लिए क्षमा करें: क्या मैं इसे grep आउटपुट को स्वीकार करने के लिए संशोधित कर सकता हूं (या इसे एक पंक्ति की तरह बना सकता हूं cat file.txt | bc?
टिम

@ मेरे एडिट्स की जाँच करें
heemayl

ता, वह सरल था!
टिम

2
जब तक मुझे एक और उत्तर नहीं मिला, जिसका मुझे उपयोग करना था, तब तक मेरे लिए काम नहीं किया paste -sd+ -। कृपया इसमें संशोधन करें।
ज़ेरुस

19

तुम भी awk का उपयोग कर सकते हैं। * .Txt फ़ाइलों में कुल पंक्तियों की गिनती करने के लिए "हैलो" शब्द शामिल हैं:

grep -ch 'hello' *.txt | awk '{n += $1}; END{print n}'

किसी फ़ाइल में संख्याओं का योग करने के लिए:

awk '{n += $1}; END{print n}' file.txt

लेकिन अगर उस लाइन का मान "4" है तो वह 4 नहीं गिनेगी। इसकी गिनती 1.
टिम

नहीं, यह 4 गिना जाएगा।
CrazyApe84

मुझे एक फ़ाइल में कुल संख्या चाहिए। क्या यह ऐसा करता है?
टिम

मुझे लगा कि आपने अपना प्रश्न grep के आउटपुट में बदल दिया है। मैं कुछ धारणा बना रहा था। मैं जोड़ता हूँ कि कैसे एक फ़ाइल में मानों का योग किया जाए।
CrazyApe84

2
हाँ। यह वास्तव में हेमेयेल के समान ही उत्तर है, लेकिन पेस्ट और बीसी के बजाय यह awk का उपयोग करता है, जो अंततः बहुत अधिक लचीलापन देता है। फिर भी, उसका जवाब अच्छा है और वह पहले था इसलिए वह आपके वोट का हकदार है!
CrazyApe84

7

numsumपैकेज से उपयोग करें num-utils!

(आपको इसकी आवश्यकता हो सकती है sudo apt-get install num-utils)

कमांड numsumआपको डिफ़ॉल्ट रूप से वही करता है जो आपको चाहिए;

$ numsum file.txt 
19

परीक्षण संख्या रेखा से पंक्ति द्वारा पढ़ना stdin:

$ printf '
1 
3
4
1
4
3
1
2' | numsum
19

या एक पंक्ति से पढ़ना:

$ printf '1 3 4 1 4 3 1 2' | numsum -r
19


अधिक उपयोगिताओं

पैकेज में नंबर प्रसंस्करण के लिए कुछ अन्य उपयोगिताओं हैं जो अधिक प्रसिद्ध होने के लायक हैं:

numaverage   - find the average of the numbers, or the mode or median
numbound     - find minimum of maximum of all lines
numgrep      - to find numbers matching ranges or sets
numinterval  - roughly like the first derivative
numnormalize - normalize numbers to an interval, like 0-1
numrandom    - random numbers from ranges or sets, eg odd.  
numrange     - similar to seq
numround     - round numbers up, down or to nearest

और अधिक सामान्य कैलकुलेटर कमांड numprocess,
जो इनपुट लाइन पर कमांड लाइन से संख्याओं पर एक अभिव्यक्ति लागू करता है।


1

आप awkप्रति लाइन एक पैटर्न के साथ फ़ाइलों को स्कैन और प्रसंस्करण के लिए एक मूल लिनक्स अनुप्रयोग उपयोगी का उपयोग कर सकते हैं । आपके प्रश्न के लिए, यह वही होगा जो आप चाहते हैं:

awk 'BEGIN { sum=0 } { sum+=$1 } END {print sum }' file.txt

पाइप भी स्वीकार कर रहे हैं:

cat file.txt | awk 'BEGIN { sum=0 } { sum+=$1 } END {print sum }'

एक BEGIN{}ब्लॉक के लिए कोई ज़रूरत नहीं है , CrazyApe84 का जवाब देखें ।
टेराडॉन

यह इस समस्या से बेमानी है, लेकिन मैंने इसे एक उपदेशात्मक उद्देश्य के कारण शामिल करना पसंद किया है।
ग्वाराह

लेकिन यह क्या सिखाता है? यह हर समस्या के लिए बेमानी awkहै, सी नहीं है, आपको इसका उपयोग करने से पहले एक चर सेट करने की आवश्यकता नहीं है। कोशिश करो awk 'BEGIN{print c+=1}'
टेराडॉन

BEGIN {}ब्लॉक को केवल वैरिएबल को इनिशियलाइज़ करने के लिए डिज़ाइन नहीं किया गया था। यह डिजाइन विनिर्देश पर भाग लेता है। तो, कुछ समस्याओं पर इसकी आवश्यकता हो सकती है।
ग्वाराह

0

यह bashस्क्रिप्टिंग का एक काफी सरल उपयोग है ।

SUM=0; for line in `cat file.txt`; do SUM=$((SUM + line)); done

यह वर्तमान समाधान की तुलना में बहुत सरल और टूलसेट न्यूनतम है।
Det

0

पर्ल समाधान:

$ perl -lnae '$c+=$_;END{print $c}' input.txt                                                                            
19

ऊपर कई फ़ाइलों में सभी नंबरों को जोड़ सकते हैं:

$ perl -lnae '$c+=$_;END{print $c}' input.txt input2.txt                                                                 
34

कमांड-लाइन पर दी गई कई फाइलों के लिए जहां हम व्यक्तिगत फाइल में संख्याओं का योग देखना चाहते हैं, हम ऐसा कर सकते हैं:

$ perl -lnae '$c+=$_;if(eof){printf("%d %s\n",$c,$ARGV);$c=0}' input.txt input2.txt                                      
19 input.txt
15 input2.txt


0

एक सरल तरीका आपके शेल की अंतर्निहित सुविधा का उपयोग करना है:

SUM=0; while read N; do SUM=$((SUM+N)); done </path/to/file
echo $SUM

यह आपकी फ़ाइल को पढ़ता है, परिणाम को प्रिंट करता है और प्रिंट करता है।

यदि आप एक पाइप का उपयोग करना चाहते हैं और केवल पहली पंक्ति का उपयोग करना चाहते हैं, तो यह इस तरह से काम करता है:

SUM=0
your_command | while read -r LINE; do for N in $LINE; do break; done; SUM=$((SUM+N)); done
echo $SUM

पहला तत्व प्राप्त करना इस तरह किया जाता है:

LIST="foo bar baz"
for OBJ in $LIST; do break; done
echo $OBJ

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