दिलचस्प पोस्ट
सी # में JSON पार्स करें क्यों Spring's ApplicationContext.getBean खराब माना जाता है? क्या सी # असिनीकृत चर खतरनाक है? समय-समय पर AJAX अनुरोध को कैसे आग लगा सकते हैं? एसएफआईएनएईए गए सदस्य कार्यों के लिए जांच मैन्युअल रूप से पायथन में एक अपवाद बढ़ाना (फेंक) jQuery स्थगित और वादों – .then () बनाम .Done () आप मूल्य से एक शब्दकोश कैसे सॉर्ट करते हैं? सिम्युलेटर में ऐप चलाने में असमर्थ: Xcode बीटा 6 IOS 8 जेनमेन इटैम का नाम ऐक्शन लास्टनर को देना पीआईपी और setup.py के साथ पायथन क्रिप्टोग्राफी पैकेज को स्थापित करने में विफल रहा क्या सी # थ्रेड वास्तव में एक मान को कैश कर सकता है और अन्य थ्रेड्स पर उस मान में परिवर्तनों को अनदेखा कर सकता है? Chrome में console.log को किसी फ़ाइल में सहेजें आईफोन सिम्युलेटर कहां स्टोर करता है? कितना ओवरहेड SSL लागू है?

शेल कमांड को पूर्णांक के लिए, एक पंक्ति प्रति एक है?

मैं एक कमांड के लिए देख रहा हूं जो पाठ के कई लाइनों के इनपुट के रूप में स्वीकार करेगा, प्रत्येक पंक्ति में एक पूर्णांक है, और इन पूर्णांक का योग आउटपुट होगा।

थोड़ी पृष्ठभूमि के रूप में, मेरे पास एक लॉग फाइल है जिसमें टाइमिंग मापन शामिल है, इसलिए संबंधित लाइनों के लिए grepping के माध्यम से, और कुछ sed रीफमैंटिंग मैं उस फ़ाइल में सभी समय की सूची कर सकता हूँ। मैं हालांकि कुल मिलाकर काम करना चाहता हूं, और किसी भी कमांड के रूप में मेरा मन रिक्त हो गया है, मैं इस मध्यवर्ती आउटपुट को अंतिम राशि के लिए पाइप कर सकता हूं। मैंने हमेशा अतीत में expr का उपयोग किया है, लेकिन जब तक कि वह RPN mode में नहीं चलता, मुझे नहीं लगता कि यह इस से निपटने वाला है (और फिर भी यह मुश्किल होगा)।

मैं क्या खो रहा हूँ? यह देखते हुए कि संभवत: इसे प्राप्त करने के कई तरीके हैं, मैं किसी भी दृष्टिकोण को पढ़ने (और upvote ) करने में प्रसन्नता होगी, भले ही किसी अन्य ने पहले से एक अलग समाधान पोस्ट किया हो जो काम करता है।

संबंधित प्रश्न: यूनिक्स पर आउटपुट के एक कॉलम के योग की गणना करने के लिए सबसे छोटी कमांड? ( क्रडिट @ एंड्रयू )


अद्यतन : वाह, जैसा कि उम्मीद है कि यहां कुछ अच्छे उत्तर दिए गए हैं ऐसा लगता है कि सामान्य रूप से command-line tool रूप में मुझे निश्चित रूप से awk गहरा निरीक्षण देना होगा!

वेब के समाधान से एकत्रित समाधान "शेल कमांड को पूर्णांक के लिए, एक पंक्ति प्रति एक है?"

Awk के बिट करना चाहिए?

 awk '{s+=$1} END {print s}' mydatafile 

नोट: यदि आप 2 ^ 31 (2147483647) से अधिक कुछ जोड़ने जा रहे हैं, तो awk के कुछ संस्करणों में कुछ अजीब व्यवहार होते हैं अधिक पृष्ठभूमि के लिए टिप्पणियां देखें एक सुझाव print बजाय printf का उपयोग करना है:

 awk '{s+=$1} END {printf "%.0f", s}' mydatafile 

चिपकाएं आम तौर पर एकाधिक फ़ाइलों की लाइनों में विलय कर लेता है, लेकिन इसका उपयोग किसी एकल पंक्ति में फ़ाइल की अलग-अलग लाइनों को रूपांतरित करने के लिए भी किया जा सकता है। सीमांकक झंडा आपको बीसी को एक्स + एक्स टाइप समीकरण पारित करने की अनुमति देता है।

 paste -s -d+ infile | bc 

वैकल्पिक रूप से, stdin से पाइपिंग करते समय,

 <commands> | paste -s -d+ - | bc 

पायथन में एक-लाइनर संस्करण:

 $ python -c "import sys; print(sum(int(l) for l in sys.stdin))" 

सादा बीश:

 $ cat numbers.txt 1 2 3 4 5 6 7 8 9 10 $ sum=0; while read num; do ((sum += num)); done < numbers.txt; echo $sum 55 
 dc -f infile -e '[+z1<r]srz1<rp' 

ध्यान दें कि शून्य से चिन्हित नकारात्मक संख्या dc लिए अनुवादित की जानी चाहिए, क्योंकि इसका उपयोग करने के बजाय _ उपसर्ग का उपयोग करता है - उस के लिए उपसर्ग उदाहरण के लिए, tr '-' '_' | dc -f- -e '...' tr '-' '_' | dc -f- -e '...'

संपादित करें: चूंकि इस जवाब को "अस्पष्टता के लिए" इतने सारे वोट मिले, इसलिए यह विस्तृत व्याख्या है:

अभिव्यक्ति [+z1<r]srz1<rp निम्न करता है :

 [ interpret everything to the next ] as a string + push two values off the stack, add them and push the result z push the current stack depth 1 push one <r pop two values and execute register r if the original top-of-stack (1) is smaller ] end of the string, will push the whole thing to the stack sr pop a value (the string above) and store it in register r z push the current stack depth again 1 push 1 <r pop two values and execute register r if the original top-of-stack (1) is smaller p print the current top-of-stack 

छद्म कोड के रूप में:

  1. "Add_top_of_stack" को परिभाषित करें:
    1. स्टैक से दो शीर्ष मूल्यों को निकालें और परिणाम वापस जोड़ें
    2. अगर स्टैक में दो या अधिक मान हैं, तो "add_top_of_stack" को फिर से चलाएं
  2. अगर स्टैक में दो या अधिक मान हैं, तो "add_top_of_stack" चलाएं
  3. परिणाम प्रिंट करें, अब स्टैक में छोड़ दिया गया एकमात्र आइटम

सचमुच dc की सादगी और शक्ति को समझने के लिए, यहां एक कामयाबी पायथन स्क्रिप्ट है जो dc से कुछ कमांड लागू करता है और उपरोक्त कमांड के पायथन संस्करण को कार्यान्वित करता है:

 ### Implement some commands from dc registers = {'r': None} stack = [] def add(): stack.append(stack.pop() + stack.pop()) def z(): stack.append(len(stack)) def less(reg): if stack.pop() < stack.pop(): registers[reg]() def store(reg): registers[reg] = stack.pop() def p(): print stack[-1] ### Python version of the dc command above # The equivalent to -f: read a file and push every line to the stack import fileinput for line in fileinput.input(): stack.append(int(line.strip())) def cmd(): add() z() stack.append(1) less('r') stack.append(cmd) store('r') z() stack.append(1) less('r') p() 

मैं आमतौर पर अनुमोदित समाधान पर एक बड़ी चेतावनी डालूंगा:

 awk '{s+=$1} END {print s}' mydatafile # DO NOT USE THIS!! 

ऐसा इसलिए है क्योंकि इस फॉर्म में awk 32 बिट हस्ताक्षरित पूर्णांक प्रतिनिधित्व का उपयोग करता है: यह 2147483647 (यानी, 2 ^ 31) के पार होने वाले रकम के लिए अतिप्रवाह होगा।

एक अधिक सामान्य जवाब (पूर्णांक के लिए) के लिए होगा:

 awk '{s+=$1} END {printf "%.0f\n", s}' mydatafile # USE THIS INSTEAD 

पीएस मुझे पहला जवाब टिप्पणी करना पसंद आया, लेकिन मेरे पास पर्याप्त प्रतिष्ठा नहीं है ..

शुद्ध और छोटी बाश

 f=$(cat numbers.txt) echo $(( ${f//$'\n'/+} )) 
 perl -lne '$x += $_; END { print $x; }' < infile.txt 

Jq के साथ:

 seq 10 | jq -s 'add' # 'add' is equivalent to 'reduce .[] as $item (0; . + $item)' 

मेरे पंद्रह सेंट:

 $ cat file.txt | xargs | sed -e 's/\ /+/g' | bc 

उदाहरण:

 $ cat text 1 2 3 3 4 5 6 78 9 0 1 2 3 4 576 7 4444 $ cat text | xargs | sed -e 's/\ /+/g' | bc 5148 

बास समाधान, यदि आप इसे एक कमांड बनाना चाहते हैं (उदाहरण के लिए यदि आपको यह अक्सर करना है):

 function addnums { TOTAL=0 while read val; do TOTAL=$(($TOTAL+$val)) done echo $TOTAL } 

तब उपयोग:

 cat /tmp/nums | addnums 

सादा बाश एक लाइनर

 $ cat > /tmp/test 1 2 3 4 5 ^D $ echo $(( $(cat /tmp/test | tr "\n" "+" ) 0 )) 

Bash में निम्न कार्य करता है:

 I=0 for N in `cat numbers.txt` do I=`expr $I + $N` done echo $I 

आप num-utils का प्रयोग कर सकते हैं, हालांकि यह आपके लिए क्या जरूरत है यह शेल में संख्याओं को छेड़छाड़ करने के लिए कार्यक्रमों का एक सेट है, और निश्चित रूप से कई निफ्टी चीजें भी कर सकती है, उन्हें जोड़कर। यह थोड़ी पुरानी है, लेकिन वे अब भी काम करते हैं और उपयोगी हो सकते हैं यदि आपको कुछ और करने की ज़रूरत है।

http://suso.suso.org/programs/num-utils/

मुझे पता है यह एक पुराना सवाल है, लेकिन मुझे इस समाधान को साझा करने के लिए पर्याप्त पसंद है।

 % cat > numbers.txt 1 2 3 4 5 ^D % cat numbers.txt | perl -lpe '$c+=$_}{$_=$c' 15 

यदि कोई रुचि है, तो मैं बताता हूं कि यह कैसे काम करता है।

शुद्ध बाश और एक-लाइनर में 🙂

 $ cat numbers.txt 1 2 3 4 5 6 7 8 9 10 $ I=0; for N in $(cat numbers.txt); do I=$(($I + $N)); done; echo $I 55 
 sed 's/^/.+/' infile | bc | tail -1 

मुझे लगता है कि ऐडब्लूके आप के लिए क्या देख रहे हैं: awk '{sum+=$1}END{print sum}'

आप इस आदेश का इस्तेमाल मानक इनपुट के माध्यम से संख्याओं की संख्या को पारित कर सकते हैं या एक पैरामीटर के रूप में संख्याओं वाले फाइल को पास कर सकते हैं।

वैकल्पिक शुद्ध पर्ल, काफी पठनीय, कोई पैकेज या विकल्प आवश्यक नहीं है:

 perl -e "map {$x += $_} <> and print $x" < infile.txt 

रूबी प्रेमी के लिए

 ruby -e "puts ARGF.map(&:to_i).inject(&:+)" numbers.txt 

आप इसे अजगर में कर सकते हैं, अगर आपको सहज महसूस होता है:

परीक्षण नहीं किया गया, बस टाइप किया गया:

 out = open("filename").read(); lines = out.split('\n') ints = map(int, lines) s = sum(ints) print s 

सेबस्टियन ने एक एक लाइनर स्क्रिप्ट को बताया:

 cat filename | python -c"from fileinput import input; print sum(map(int, input()))" 

निम्नलिखित कार्य करना चाहिए (प्रत्येक नंबर पर अपना नंबर संभालना दूसरा नंबर है)।

 awk 'BEGIN {sum=0} \ {sum=sum + $2} \ END {print "tot:", sum}' Yourinputfile.txt 

रैकेट में एक-लाइनर:

 racket -e '(define (g) (define i (read)) (if (eof-object? i) empty (cons i (g)))) (foldr + 0 (g))' < numlist.txt 

सी (सरलीकृत नहीं)

 seq 1 10 | tcc -run <(cat << EOF #include <stdio.h> int main(int argc, char** argv) { int sum = 0; int i = 0; while(scanf("%d", &i) == 1) { sum = sum + i; } printf("%d\n", sum); return 0; } EOF) 

मेरा संस्करण:

 seq -5 10 | xargs printf "- - %s" | xargs | bc 

मैंने मौजूदा उत्तर पर एक त्वरित बेंचमार्क किया है जो

  • केवल मानक उपकरण का उपयोग करें ( lua या rocket जैसी चीजों के लिए खेद है),
  • असली एक liners हैं,
  • बड़ी संख्या में संख्याएं जोड़ने में सक्षम हैं (100 मिलियन), और
  • तेज़ हैं (मैं उन लोगों को नजरअंदाज कर रहा हूं जो एक मिनट से ज्यादा समय लगे)।

मैंने हमेशा 1 से 100 मिलियन की संख्या जोड़ दी जो कि मेरे मशीन पर कई समाधानों के लिए एक मिनट से भी कम समय में सक्षम था।

यहां परिणाम दिए गए हैं:

अजगर

 :; seq 100000000 | python -c 'import sys; print sum(map(int, sys.stdin))' 5000000050000000 # 30s :; seq 100000000 | python -c 'import sys; print sum(int(s) for s in sys.stdin)' 5000000050000000 # 38s :; seq 100000000 | python3 -c 'import sys; print(sum(int(s) for s in sys.stdin))' 5000000050000000 # 27s :; seq 100000000 | python3 -c 'import sys; print(sum(map(int, sys.stdin)))' 5000000050000000 # 22s :; seq 100000000 | pypy -c 'import sys; print(sum(map(int, sys.stdin)))' 5000000050000000 # 11s :; seq 100000000 | pypy -c 'import sys; print(sum(int(s) for s in sys.stdin))' 5000000050000000 # 11s 

awk

 :; seq 100000000 | awk '{s+=$1} END {print s}' 5000000050000000 # 22s 

चिपकाएं और बीसी

यह मेरे मशीन पर स्मृति से बाहर भाग गया यह इनपुट के आधे आकार के लिए काम किया (50 मिलियन संख्या):

 :; seq 50000000 | paste -s -d+ - | bc 1250000025000000 # 17s :; seq 50000001 100000000 | paste -s -d+ - | bc 3750000025000000 # 18s 

तो मुझे लगता है कि यह 100 मिलियन संख्याओं के लिए 35 के स्तर तक ले जाएगा।

पर्ल

 :; seq 100000000 | perl -lne '$x += $_; END { print $x; }' 5000000050000000 # 15s :; seq 100000000 | perl -e 'map {$x += $_} <> and print $x' 5000000050000000 # 48s 

माणिक

 :; seq 100000000 | ruby -e "puts ARGF.map(&:to_i).inject(&:+)" 5000000050000000 # 30s 

सी

बस तुलना की वजह से मैंने सी संस्करण संकलित किया और यह भी परीक्षण किया, बस एक विचार है कि टूल आधारित समाधान कितने धीमे हैं

 #include <stdio.h> int main(int argc, char** argv) { long sum = 0; long i = 0; while(scanf("%ld", &i) == 1) { sum = sum + i; } printf("%ld\n", sum); return 0; } 

 :; seq 100000000 | ./a.out 5000000050000000 # 8s 

निष्कर्ष

सी सबसे तेज 8s के साथ है, लेकिन Pypy समाधान केवल लगभग 30% से 11 के एक बहुत कम उपरि जोड़ता है । लेकिन, निष्पक्ष होना, Pypy बिल्कुल मानक नहीं है। अधिकांश लोगों में केवल CPython स्थापित होता है जो कि काफी धीमी है (22s), जो कि लोकप्रिय एवक समाधान के समान है।

मानक उपकरणों पर आधारित सबसे तेज समाधान पर्ल (15) है।

या sed के बजाय awk का उपयोग करें: अंकगणितीय नमूना

एडब्ल्यूके का पहले से उल्लेख किया जा चुका है, इसके अलावा मैं यह सुझाव देना चाहूंगा कि मूल लॉग फाइल को स्कैन करने के लिए आप जीआरईपी और एसएडी के बजाय इस भाषा का उपयोग करें। एक उपयुक्त एडब्ल्यूके स्क्रिप्ट आसानी से दोनों की नौकरी कर सकती है और पॉल और एल्फ़ ने पहले ही बताया है कि दिलचस्प मूल्य की गणना कर सकते हैं।

 $ बिल्ली n
 2
 4
 2
 7
 8
 9
 $ perl -MList::Util -le 'print List::Util::sum(<>)' < n 32 

या, आप कमांड लाइन पर नंबरों में टाइप कर सकते हैं:

 $ perl -MList::Util -le 'print List::Util::sum(<>)' 1 3 5 ^D 9 

हालांकि, यह एक फ़ाइल को दबाता है इसलिए बड़ी फ़ाइलों पर उपयोग करने के लिए यह एक अच्छा विचार नहीं है देखें j_random_hacker का जवाब जो slurping से बचा जाता है।

बैकटीक्स ("`) की पठनीयता के लिए अग्रिम रूप से क्षमा चाहते हैं, लेकिन ये कार्य बाश के अलावा अन्य गोले में हैं और इस प्रकार यह अधिक पेस्टेबल है। यदि आप एक शेल का उपयोग करते हैं जो इसे स्वीकार करता है, तो $ (कमांड …) प्रारूप `आदेश … की तुलना में अधिक पठनीय है (और इस तरह डीबग) … इसलिए अपने विवेक के लिए संशोधित करने के लिए स्वतंत्र महसूस करें

मेरे बाश्रक्र में मेरे पास एक सरल कार्य है जो कि कई गणित वस्तुओं की गणना करने के लिए awk का उपयोग करेगा

 calc(){ awk 'BEGIN{print '$@' }' } 

यह +, -, *, /, ^,%, sqrt, पाप, कॉस, कोष्ठक … …. और (और अधिक आपके awk के संस्करण के आधार पर) करेंगे … आप printf और फ़ोट़िंग पॉइंट के साथ फ़ैंसी भी प्राप्त कर सकते हैं उत्पादन, लेकिन यह सब मैं सामान्य रूप से जरूरत है

इस विशेष सवाल के लिए, मैं बस प्रत्येक पंक्ति के लिए ऐसा करेंगे:

 calc `echo $@|tr " " "+"` 

इसलिए प्रत्येक पंक्ति में जमा करने के लिए कोड ब्लॉक कुछ ऐसा दिखाई देगा:

 while read LINE || [ "$LINE" ]; do calc `echo $LINE|tr " " "+"` #you may want to filter out some lines with a case statement here done 

ऐसा तब होता है जब आप लाइन से लाइन को जोड़ना चाहते हैं हालांकि डेटाफ़ाइल में कुल संख्या के लिए

 VARS=`<datafile` calc `echo ${VARS// /+}` 

बीटीडब्ल्यू अगर मुझे डेस्कटॉप पर कुछ जल्दी करना है, तो मैं इसका उपयोग करता हूं:

 xcalc() { A=`calc $@` A=`Xdialog --stdout --inputbox "Simple calculator" 0 0 $A` [ $A ] && xcalc $A }