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


866

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

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

मुझे पूर्णांकों का योग कैसे मिल सकता है?


2
यह कुछ समय पहले पूछे गए प्रश्न के समान है: stackoverflow.com/questions/295781/…
Anrewdrew

5
मैं वास्तव में इस तथ्य को पसंद करता हूं कि बहुत सारे सही (या कम से कम काम करने वाले) उत्तर हैं।
फ्रांसिस्को कैनेडो

यह सवाल कोड गोल्फ के लिए एक समस्या की तरह लगता है। codegolf.stackexchange.com :)
गॉर्डन बीन

जवाबों:


1321

बिटकॉइन ऑफ awk इसे करना चाहिए?

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

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

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

7
इस कमरे में बहुत अजीब प्यार है! मुझे पसंद है कि कैसे इस तरह की एक साधारण स्क्रिप्ट को $ 1 से $ 2 में बदलकर डेटा का दूसरा कॉलम जोड़ने के लिए संशोधित किया जा सकता है
पॉल डिक्सन

2
एक व्यावहारिक सीमा नहीं है, क्योंकि यह इनपुट को एक धारा के रूप में संसाधित करेगा। तो, अगर यह एक्स लाइनों की एक फ़ाइल को संभाल सकता है, तो आप सुनिश्चित कर सकते हैं कि यह X + 1 को संभाल सकता है।
पॉल डिक्सन

4
मैंने एक बार अवकाश उपयोगिता के माध्यम से एक अजीब स्क्रिप्ट रन के साथ एक अल्पविकसित मेलिंग सूची प्रोसेसर लिखा था। अच्छा समय। :)
LS

2
बस इसके लिए इसका उपयोग किया गया था: सभी दस्तावेजों की पेज स्क्रिप्ट की गिनती करें:ls $@ | xargs -i pdftk {} dump_data | grep NumberOfPages | awk '{s+=$2} END {print s}'
भेड़

8
सावधान रहें, यह 2147483647 (यानी, 2 ^ 31) से अधिक संख्या के साथ काम नहीं करेगा, ऐसा इसलिए है क्योंकि awk एक 32 बिट हस्ताक्षरित पूर्णांक प्रतिनिधित्व का उपयोग करता है। awk '{s+=$1} END {printf "%.0f", s}' mydatafileइसके बजाय उपयोग करें ।
गियान्कार्लो स्पोर्टेली

665

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

paste -s -d+ infile | bc

वैकल्पिक रूप से, जब स्टिंग से पाइपिंग,

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

1
बहुत अच्छा! मैंने "+" से पहले एक स्थान रखा होगा, बस मुझे इसे बेहतर तरीके से पार्स करने में मदद करने के लिए, लेकिन यह पेस्ट और फिर बीसी के माध्यम से कुछ मेमोरी नंबर को पाइप करने के लिए बहुत आसान था।
माइकल एच।

73
बहुत आसान याद है और जाग समाधान से टाइप करें। इसके अलावा, ध्यान दें कि फ़ाइल नाम के रूप में pasteएक डैश का उपयोग कर सकते हैं -- जो आपको पहले फ़ाइल बनाने की आवश्यकता के बिना पेस्ट के मानक आउटपुट में एक कमांड के आउटपुट से संख्याओं को पाइप करने की अनुमति देगा:<commands> | paste -sd+ - | bc
जॉर्ज

19
मेरे पास 100 मिलियन नंबरों वाली फाइल है। Awk कमांड 21s लेता है; पेस्ट कमांड को 41s लगते हैं। लेकिन फिर भी 'पेस्ट' मिलना अच्छा है!
अभि

4
@ आभी: दिलचस्प: डि का अनुमान है कि मुझे 20 सेकंड लगेंगे, क्योंकि जाग कमांड का पता लगाने के लिए यह 100 मिलियन और एक नंबर की कोशिश करने के बाद भी बाहर निकलता है: डी
मार्क के कोवन

6
@ जॉर्ज आप बाहर छोड़ सकते हैं -, यद्यपि। (यह उपयोगी है यदि आप एक फ़ाइल को स्टडिन के साथ जोड़ना चाहते थे )।
एलोइस महदाल

128

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

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

एक-लाइनर ऊपर
sys.argv

सच- लेखक ने कहा कि वह कमांड में एक अन्य स्क्रिप्ट से आउटपुट करने जा रहा था और मैं इसे यथासंभव छोटा बनाने की कोशिश कर रहा था :)
डीएफ।

39
छोटा संस्करण होगाpython -c"import sys; print(sum(map(int, sys.stdin)))"
jfs

4
मुझे यह उत्तर पढ़ने और लचीलेपन में आसानी के लिए पसंद है। मुझे निर्देशिकाओं के संग्रह में 10Mb से छोटी फ़ाइलों के औसत आकार की आवश्यकता थी और इसे इस पर संशोधित किया:find . -name '*.epub' -exec stat -c %s '{}' \; | python -c "import sys; nums = [int(n) for n in sys.stdin if int(n) < 10000000]; print(sum(nums)/len(nums))"
पॉल व्हिप

1
यदि आपके पास कुछ पाठ मिलाया गया है, तो आप गैर संख्याओं को भी फ़िल्टर कर सकते हैं:import sys; print(sum(int(''.join(c for c in l if c.isdigit())) for l in sys.stdin))
ग्रानिटोसॉरस

91

मैं आमतौर पर स्वीकृत समाधान पर एक बड़ा चेतावनी देता हूँ:

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

Printf () यहाँ क्यों मदद करता है? इंट का ओवरफ्लो इससे पहले हुआ होगा क्योंकि समन कोड समान है।
रॉबर्ट क्लेमे

9
क्योंकि समस्या वास्तव में "प्रिंट" फ़ंक्शन में है। Awk 64 बिट पूर्णांक का उपयोग करता है, लेकिन किसी कारण के लिए उन्हें 32 बिट में प्रिंट करता है।
जियानकार्लो स्पोर्टेली

4
प्रिंट बग निश्चित रूप से प्रतीत होता है, कम से कम awk 4.0.1 और bash 4.3.11 के लिए, जब तक मैं गलत नहीं हूँ: echo -e "2147483647 \n 100" |awk '{s+=$1}END{print s}'शो2147483747
Xen2050

4
तैरता का उपयोग करते हुए सिर्फ एक नई समस्या का परिचय: echo 999999999999999999 | awk '{s+=$1} END {printf "%.0f\n", s}'पैदा करता है1000000000000000000
पैट्रिक

1
64 बिट सिस्टम पर "% ld" का उपयोग नहीं करना चाहिए क्या 32 बिट के लिए प्रिंटफ ट्रंकट नहीं है? जैसा कि @ पैट्रिक बताते हैं, यहां तैरना एक महान विचार नहीं है।
yerforkferchips

78

सादे बैश:

$ 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


@jjack, कहाँ numपरिभाषित किया गया है? मेरा मानना ​​है कि किसी तरह यह < numbers.txtअभिव्यक्ति से जुड़ा है , लेकिन यह स्पष्ट नहीं है कि कैसे।
Atcold

66
dc -f infile -e '[+z1<r]srz1<rp'

ध्यान दें कि ऋणात्मक संख्या के साथ उपसर्ग किए गए ऋणात्मक संख्याओं का अनुवाद करना चाहिए dc, क्योंकि यह _उपसर्ग के बजाय उपसर्ग का उपयोग करता -है। उदाहरण के लिए, के माध्यम से 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()

2
डीसी सिर्फ पसंद का उपकरण है। लेकिन मैं इसे थोड़ा कम स्टैक ऑप्स के साथ करूंगा। माना कि सभी लाइनों में वास्तव में एक संख्या होती है (echo "0"; sed 's/$/ +/' inp; echo 'pq')|dc:।
ikrabbe

5
ऑनलाइन एल्गोरिथ्म dc -e '0 0 [+?z1<m]dsmxp':। इसलिए हम प्रसंस्करण से पहले स्टैक पर सभी नंबरों को नहीं बचाते हैं, लेकिन उन्हें एक-एक करके पढ़ते हैं और संसाधित करते हैं (अधिक सटीक होने के लिए, लाइन द्वारा लाइन, क्योंकि एक लाइन में कई नंबर शामिल हो सकते हैं)। ध्यान दें कि खाली रेखा एक इनपुट अनुक्रम को समाप्त कर सकती है।
रुविम

@ikrabbe यह बहुत अच्छा है। यह वास्तव में एक और चरित्र द्वारा छोटा किया जा सकता है: sedप्रतिस्थापन में स्थान को हटाया जा सकता है, क्योंकि dc तर्कों और ऑपरेटरों के बीच रिक्त स्थान की परवाह नहीं करता है। (echo "0"; sed 's/$/+/' inputFile; echo 'pq')|dc
व्हाइटहोटलवॉटर टाइगर

58

Jq के साथ :

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

7
मुझे यह पसंद है क्योंकि मुझे लगता है कि यह इतना स्पष्ट और छोटा है कि मैं वास्तव में इसे याद रख पाऊंगा।
अल्फ

46

शुद्ध और कम बैश।

f=$(cat numbers.txt)
echo $(( ${f//$'\n'/+} ))

9
यह सबसे अच्छा समाधान है क्योंकि यह किसी भी उपप्रकार का निर्माण नहीं करता है यदि आप पहली पंक्ति को बदलते हैं f=$(<numbers.txt)
लोवेंटार

1
स्टड से इनपुट होने का कोई तरीका? पाइप से पसंद है?
njzk2

@ njzk2 यदि आप f=$(cat); echo $(( ${f//$'\n'/+} ))किसी स्क्रिप्ट में डालते हैं , तो आप उस स्क्रिप्ट को कुछ भी पाइप कर सकते हैं या इंटरैक्टिव स्टड इनपुट (कंट्रोल-डी के साथ समाप्त) के लिए तर्क के बिना इसे लागू कर सकते हैं।
mklement0

5
@loentar <numbers.txtएक सुधार है, लेकिन, कुल मिलाकर, यह समाधान केवल छोटी इनपुट फ़ाइलों के लिए कुशल है; उदाहरण के लिए, 1,000 इनपुट लाइनों की एक फ़ाइल के साथ स्वीकृत awkसमाधान मेरी मशीन पर लगभग 20 गुना तेज है - और कम मेमोरी भी खपत करता है, क्योंकि फ़ाइल को एक बार में पढ़ा नहीं जाता है।
mklement0

2
जब मैं इस तक पहुँच गया था तब मैंने लगभग उम्मीद खो दी थी। शुद्ध बैश!
ओमर अख्तर

37
perl -lne '$x += $_; END { print $x; }' < infile.txt

4
और मैंने उन्हें वापस जोड़ा: "-l" यह सुनिश्चित करता है कि आउटपुट एलएफ-टर्मिनेटेड है क्योंकि शेल `बैकटिक्स और अधिकांश कार्यक्रमों की उम्मीद है, और" <"इंगित करता है कि इस कमांड का उपयोग पाइप लाइन में किया जा सकता है।
j_random_hacker

तुम सही हो। बहाने के रूप में: पर्ल वन-लाइनर्स में प्रत्येक चरित्र को मेरे लिए एक मानसिक कार्य की आवश्यकता होती है, इसलिए मैं यथासंभव अधिक से अधिक किरदार करना पसंद करता हूं। आदत इस मामले में हानिकारक थी।
JFS

2
कुछ समाधानों में से एक जो सब कुछ रैम में लोड नहीं करता है।
एरिक एरोनिटी

28

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

$ 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

मेरे इनपुट में रिक्त लाइनें शामिल हो सकती हैं, इसलिए मैंने आपके द्वारा यहां पोस्ट की गई प्लस का उपयोग किया था grep -v '^$'। धन्यवाद!
जेम्स ओर्वेक

वाह!! आपका जवाब अद्भुत है! मेरे सभी पसंदीदा से चलने में
thahgr

इसे प्यार करें और पाइपलाइन के लिए +1। मेरे लिए बहुत ही सरल और आसान उपाय
जेलिन लुओ

24

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

  • केवल मानक उपकरणों का उपयोग करें (जैसे luaया सामान के लिए क्षमा करें rocket),
  • असली एक-लाइनर हैं,
  • बड़ी संख्या में (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 मिलियन नंबरों के लिए ~ 35s लिया होगा।

पर्ल

:; 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% से 11s के बारे में बहुत कम ओवरहेड जोड़ता है । लेकिन, निष्पक्ष होने के लिए, Pypy बिल्कुल मानक नहीं है। अधिकांश लोगों के पास केवल CPython स्थापित है जो कि काफी धीमी (22s) है, बिल्कुल लोकप्रिय Awk समाधान के रूप में।

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


2
paste+ bcदृष्टिकोण क्या मैं योग के स मान लिए देख रहा था था, धन्यवाद!
टॉमिस्लाव नैक-अल्फेयरविक

1
बस मज़े के लिए, जंग में:use std::io::{self, BufRead}; fn main() { let stdin = io::stdin(); let mut sum: i64 = 0; for line in stdin.lock().lines() { sum += line.unwrap().parse::<i64>().unwrap(); } println!("{}", sum); }
Jocelyn

जबरदस्त जवाब। नाइटपिक के लिए नहीं, लेकिन यह मामला है कि अगर आपने उन लंबे समय तक चलने वाले परिणामों को शामिल करने का फैसला किया, तो इसका जवाब और भी भयानक होगा!
स्टीवन लू

@StevenLu मुझे लगा कि उत्तर बस लंबा होगा और इस तरह कम भयानक (अपने शब्दों का उपयोग करने के लिए)। लेकिन मैं समझ सकता हूं कि इस भावना को हर किसी के द्वारा साझा नहीं किया जाना चाहिए :)
अल्फ

अगला: Numba + parallelisation
Gerrit


17

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

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

फिर उपयोग:

addnums < /tmp/nums

14

मुझे लगता है कि AWK तुम क्या देख रहे हो:

awk '{sum+=$1}END{print sum}'

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


2
यह एक
डुबकी है

11

निम्नलिखित कार्य बाश में हैं:

I=0

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

echo $I

1
कमांड विस्तार का उपयोग सावधानी के साथ किया जाना चाहिए जब फाइलें मनमाने ढंग से बड़ी हो सकती हैं। 10MB के नंबर के साथ, cat numbers.txtकदम समस्याग्रस्त होगा।
जियाकोमो

1
हालांकि, हालांकि (यदि यहां पाए गए बेहतर समाधानों के लिए नहीं) मैं इसका इस्तेमाल तब तक करूंगा जब तक कि मुझे वास्तव में उस समस्या का सामना नहीं करना पड़ता।
फ्रांसिस्को कैनेडो

11

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

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


उदाहरण: numsum numbers.txt
agc

9

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

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

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


10
कृपया नहीं। हम चाहते हैं कि -n नाटक करने के लिए पसंद है और -p अच्छा अर्थ बातें ही नहीं, कुछ चतुर स्ट्रिंग चिपकाने कर रहे हैं;)
हॉब्स

2
हाँ कृपया, समझाएँ :) (मैं एक पर्ल टाइपिया आदमी नहीं हूँ।)
जेन्स

1
"Perl -MO = Deparse -lpe '$ c + = $ _} {$ _ = $ c' चलाने की कोशिश करें और आउटपुट को देखते हुए, -l मूल रूप से newlines और इनपुट और आउटपुट सेपरेटर दोनों का उपयोग करता है, और -p अपनी लाइन प्रिंट करता है। लेकिन '-p' करने के लिए, पर्ल पहले कुछ बॉयलर प्लेट जोड़ता है (जो -MO = Deparse) आपको दिखाएगा, लेकिन फिर यह सिर्फ विकल्प और संकलन करता है। इस प्रकार आप '} {' 'भाग के साथ एक अतिरिक्त ब्लॉक डाल सकते हैं और इसे प्रत्येक पंक्ति में न छापने के लिए ट्रिक कर सकते हैं, लेकिन बहुत अंत में प्रिंट कर सकते हैं।
18

9

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

$ 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

दो ((कोष्ठक क्यों हैं ))?
एटकोल्ड

बिल्ली के कारण वास्तव में शुद्ध बैश नहीं। बिल्ली को जगह देकर शुद्ध बैश $(< numbers.txt)
बनाएं


6

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

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

या थोड़ा छोटा: perl -e 'map {$ x + = $ _} <>; $ x 'infile.txt
Avi Tevet

10 मिलियन नंबरों के बड़े इनपुट के लिए मेमोरी की आवश्यकता लगभग 2GB है
अमित नायडू


5

इसे सबमिट करने से बचें:

jot 1000000 | sed '2,$s/$/+/;$s/$/p/' | dc

यह यहाँ पर पाया गया है:
सबसे सुंदर यूनिक्स खोल एक-लाइनर को मनमानी परिशुद्धता की संख्या की सूची के लिए?

और यहाँ जाग, bc और दोस्तों पर इसके विशेष लाभ हैं:

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

कृपया उत्तर में प्रश्न से संबंधित कोड और एक लिंक का संदर्भ न दें
Ibo

5

का उपयोग करते हुए जीएनयू datamash util :

seq 10 | datamash sum 1

आउटपुट:

55

यदि इनपुट डेटा अनियमित है, तो विषम स्थानों पर रिक्त स्थान और टैब के साथ, यह भ्रमित हो सकता है datamash, फिर या तो -Wस्विच का उपयोग करें:

<commands...> | datamash -W sum 1

... या trव्हाट्सएप को साफ करने के लिए उपयोग करें:

<commands...> | tr -d '[[:blank:]]' | datamash sum 1


3

आप इसे अजगर में कर सकते हैं, यदि आप सहज महसूस करते हैं:

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

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()))"

python -c "fileinput इंपोर्ट इनपुट से; प्रिंट सम (नक्शा (इंट, इनपुट ())"
नंबर। txt

2
बिल्ली का अति प्रयोग किया जाता है, फ़ाइल से रीडायरेक्ट किया जाता है: अजगर-सी "..." <नंबर। txt
जियाकोमो

2
@rjack: catयह प्रदर्शित करने के लिए प्रयोग किया जाता है कि स्क्रिप्ट stdin के लिए और argv [] ( while(<>)Perl की तरह ) फ़ाइलों के लिए दोनों काम करती है । यदि आपका इनपुट किसी फाइल में है तो '<' अनावश्यक है।
16:00 बजे jfs

2
लेकिन < numbers.txtयह दर्शाता है कि यह स्टड पर काम करता है और साथ ही साथ cat numbers.txt |करता है। और यह बुरी आदतों को नहीं सिखाता है।
Xiong Chiamiov

3
$ बिल्ली एन
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 का जवाब जो गाली देने से बचता है।


3

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

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

2
आपको वास्तव में {sum = 0} भाग की आवश्यकता नहीं है
Uphill_ What '1

3

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

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

3

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

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)

मुझे टिप्पणी को उकेरना था। उत्तर में कुछ भी गलत नहीं है - यह काफी अच्छा है। हालाँकि, यह दिखाने के लिए कि टिप्पणी उत्तर को भयानक बना रही है, मैं टिप्पणी पर ध्यान नहीं दे रहा हूँ।
बबलडवे ०२५

3

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

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

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

यह +, -, *, /, ^,%, sqrt, sin, cos, parenthesis .... (और अधिक आपके awk के संस्करण पर निर्भर करता है) करेगा ... आप प्रिंटफ और प्रारूप फ़्लोटिंग पॉइंट के साथ फैंसी भी प्राप्त कर सकते हैं। आउटपुट, लेकिन यह सब मुझे सामान्य रूप से चाहिए

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

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// /+}`

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

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

2
आप किस प्राचीन शेल का उपयोग कर रहे हैं जो समर्थन नहीं करता है $()?
nyuszika7h
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.