한 줄에 하나씩 정수를 합하는 쉘 명령?


867

여러 줄의 텍스트를 입력하고 각 줄에 단일 정수가 들어 있고 이러한 정수의 합계를 출력하는 명령을 찾고 있습니다.

약간의 배경으로, 타이밍 측정을 포함하는 로그 파일이 있습니다. 관련 줄에 대한 grepping과 약간의 sed재 포맷을 통해 해당 파일의 모든 타이밍을 나열 할 수 있습니다. 나는 총계를 해결하고 싶습니다. 최종 합계를 수행하기 위해이 중간 출력을 모든 명령에 파이프 할 수 있습니다. 나는 항상 expr과거에 사용했지만 RPN 모드에서 실행되지 않으면 이것에 대처할 것이라고 생각하지 않습니다 (그리고 심지어 까다로울 것입니다).

정수의 합계를 어떻게 얻을 수 있습니까?


2
이것은 내가 전에 한 질문과 매우 유사합니다 : stackoverflow.com/questions/295781/…
An̲̳̳drew

5
나는 가능한 많은 정답 (또는 적어도 작동)이 있다는 사실 때문에이 질문을 정말로 좋아합니다.
Francisco Canedo

이 질문은 코드 골프의 문제처럼 느껴집니다. codegolf.stackexchange.com :)
Gordon Bean

답변:


1322

조금 어색해야합니까?

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

참고 : 2 ^ 31 (2147483647)을 초과하는 항목을 추가하려는 경우 일부 버전의 awk에서 이상한 동작이 발생합니다. 더 많은 배경에 대한 의견을 참조하십시오. 한 가지 제안은 다음 printf보다는 사용 하는 것입니다 print.

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

7
이 방에는 많은 사랑이 있습니다! 나는 이와 같은 간단한 스크립트를 수정하여 $ 1에서 $ 2로 변경하여 두 번째 데이터 열을 추가하는 방법을 좋아합니다
Paul Dixon

2
입력을 스트림으로 처리하기 때문에 실질적인 한계는 없습니다. 따라서 X 줄의 파일을 처리 할 수 ​​있다면 X + 1을 처리 할 수있을 것입니다.
Paul Dixon

4
나는 휴가 유틸리티를 통해 실행되는 awk 스크립트로 초보 메일 링리스트 프로세서를 작성했습니다. 좋은 시간. :)
LS

2
방금이 문서를 다음 용도로 사용했습니다 : 모든 문서의 페이지 수를 계산하십시오 스크립트ls $@ | xargs -i pdftk {} dump_data | grep NumberOfPages | awk '{s+=$2} END {print s}'
날으는 양

8
awk는 32 ​​비트 부호있는 정수 표현을 사용하기 때문에 2147483647보다 큰 숫자 (예 : 2 ^ 31)에서는 작동하지 않습니다. awk '{s+=$1} END {printf "%.0f", s}' mydatafile대신 사용하십시오 .
Giancarlo Sportelli

665

붙여 넣기는 일반적으로 여러 파일의 행을 병합하지만 파일의 개별 행을 단일 행으로 변환하는 데 사용될 수도 있습니다. 분리 문자 플래그를 사용하면 x + x 유형 방정식을 bc에 전달할 수 있습니다.

paste -s -d+ infile | bc

또는 stdin에서 배관 할 때

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

1
아주 좋아요! "+"앞에 공백을두면 더 잘 구문 분석하는 데 도움이되지만 paste & then bc를 통해 일부 메모리 번호를 파이핑하는 데 매우 편리했습니다.
Michael H.

73
awk 솔루션보다 기억하고 입력하기가 훨씬 쉽습니다. 또한 파일 이름 paste으로 대시 -를 사용할 수 있습니다. 이렇게 하면 파일을 먼저 만들 필요없이 명령 출력의 숫자를 붙여 넣기의 표준 출력으로 파이프 할 수 있습니다.<commands> | paste -sd+ - | bc
George

19
1 억 개의 숫자가있는 파일이 있습니다. awk 명령은 21 초가 걸립니다. 붙여 넣기 명령은 41 초가 걸립니다. 그럼에도 불구하고 '붙여 넣기'를 만나는 것이 좋습니다!
Abhi

4
D : @Abhi은 : 재미 : DI 내가 100 만 하나의 번호를 시도 할 때까지 비록이 고르게 그래서 awk 명령 알아 내기 위해 나에게 20 대 걸릴 것 같아요
마크 K 코완

6
@George -하지만을 생략 할 수 있습니다 . 파일 stdin 결합하려는 경우 유용합니다 .
Alois Mahdal

128

파이썬에서 한 줄짜리 버전 :

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

위의 한 줄짜리 파일은 sys.argv []의 파일에는 작동하지 않지만 stackoverflow.com/questions/450799/…에 해당합니다.
jfs

사실-저자는 다른 스크립트의 출력을 명령으로 파이프 할 것이라고 말했으며 가능한 한 짧게 만들려고했습니다
.

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))"
Paul Whipp

1
다음과 같이 혼합 된 텍스트가있는 경우 숫자가 아닌 것을 필터링 할 수도 있습니다.import sys; print(sum(int(''.join(c for c in l if c.isdigit())) for l in sys.stdin))
Granitosaurus

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 ()가 도움이되는 이유는 무엇입니까? 합산 코드가 동일하기 때문에 int의 오버플로가 발생했을 것입니다.
Robert Klemme

9
문제는 실제로 "인쇄"기능에 있기 때문입니다. Awk는 64 비트 정수를 사용하지만 어떤 이유로 든 인쇄 동글은 32 비트로 스케일됩니다.
Giancarlo Sportelli

4
내가 잘못 생각하지 않는 한 인쇄 버그는 적어도 awk 4.0.1 및 bash 4.3.11에서는 수정 된 것으로 보입니다. echo -e "2147483647 \n 100" |awk '{s+=$1}END{print s}'shows2147483747
Xen2050

4
float를 사용하면 새로운 문제가 발생합니다. echo 999999999999999999 | awk '{s+=$1} END {printf "%.0f\n", s}'생성1000000000000000000
Patrick

1
64 비트 시스템에서 "% ld"만 사용하여 printf가 32 비트로 잘리지 않아야합니까? @Patrick이 지적했듯이, 수레는 여기에 좋은 생각이 아닙니다.
yerforkferchips 2016 년

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


@rjack, 어디에 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하고 위 명령의 Python 버전을 실행하는 작동하는 Python 스크립트가 있습니다 .

### 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
dc는 사용하는 도구입니다. 그러나 나는 조금 적은 스택 연산으로 그것을 할 것입니다. 모든 행에 실제로 숫자가 있다고 가정합니다 (echo "0"; sed 's/$/ +/' inp; echo 'pq')|dc.
ikrabbe

5
온라인 알고리즘 : dc -e '0 0 [+?z1<m]dsmxp'. 따라서 처리하기 전에 모든 숫자를 스택에 저장하지 않고 하나씩 읽고 처리합니다 (한 줄에 여러 개의 숫자가 포함될 수 있으므로 한 줄씩 더 정확하게). 빈 줄은 입력 순서를 종료 할 수 있습니다.
ruvim

@ikrabbe 대단하다. 인수와 연산자 사이의 공백을 신경 쓰지 않으므로 sed대체로 공백을 제거 할 수 있습니다 dc. (echo "0"; sed 's/$/+/' inputFile; echo 'pq')|dc
WhiteHotLoveTiger 2016 년

58

JQ :

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

7
나는 그것이 실제로 그것을 기억할 수있을 정도로 명확하고 짧다고 생각하기 때문에 이것을 좋아한다.
Alfe

46

순수하고 짧은 배쉬.

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

9
첫 번째 줄을로 바꾸면 하위 프로세스가 생성되지 않으므로 최상의 솔루션입니다 f=$(<numbers.txt).
loentar

1
stdin에서 입력을 얻는 방법은 무엇입니까? 파이프처럼?
njzk2

@ njzk2 f=$(cat); echo $(( ${f//$'\n'/+} ))스크립트 를 넣으면 대화식 stdin 입력 (Control-D로 종료)에 대한 인수없이 해당 스크립트로 무엇이든 파이프하거나 스크립트를 호출 할 수 있습니다.
mklement0

5
@loentar <numbers.txt개선 된 기능이지만 전체적으로이 솔루션은 작은 입력 파일에만 효율적입니다. 예를 들어, 1,000 입력 라인의 파일을 사용하면 허용되는 awk솔루션이 내 컴퓨터에서 약 20 배 빠르며 파일을 한 번에 읽지 않기 때문에 메모리를 덜 소비합니다.
mklement0

2
나는 이것에 도달했을 때 거의 희망을 잃었다. 순수한 배쉬!
Omer Akhter

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

4
"-l"은 쉘``백틱으로 예상되는대로 출력이 LF로 종료되고 대부분의 프로그램이 예상하는 것을 보장하며 "<"는이 명령이 파이프 라인에서 사용될 수 있음을 나타냅니다.
j_random_hacker 2016 년

네 말이 맞아 변명으로 : Perl one-liners의 각 캐릭터는 나를 위해 정신적 인 작업을 필요로하므로 가능한 한 많은 캐릭터를 제거하는 것을 선호합니다. 이 경우 습관은 해 롭습니다.
jfs

2
RAM에 모든 것을로드하지 않는 몇 가지 솔루션 중 하나입니다.
Erik Aronesty

28

나의 15 센트 :

$ 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 '^$'. 감사!
James Oravec

와!! 당신의 대답은 훌륭합니다! 트레드의 모든에서 내 개인 좋아하는
thahgr

이것을 좋아하고 파이프 라인에 +1하십시오. 나를위한 매우 간단하고 쉬운 솔루션
Gelin Luo

24

기존 답변에 대한 빠른 벤치 마크를 수행했습니다.

  • 표준 도구 만 사용하십시오 ( lua또는 같은 것들에 대해서는 죄송합니다 rocket).
  • 진짜 원 라이너입니다
  • 엄청난 양의 숫자 (1 억)를 추가 할 수 있으며
  • 빠릅니다 (분 이상 걸리는 것을 무시했습니다).

나는 항상 몇 가지 솔루션에 대해 1 분 안에 내 컴퓨터에서 가능한 1 ~ 1 억의 숫자를 추가했습니다.

결과는 다음과 같습니다.

파이썬

:; 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

어 wk

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

붙여 넣기 및 BC

컴퓨터의 메모리가 부족합니다. 입력 크기의 절반 (5 천만 숫자)으로 작동했습니다.

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

그래서 1 억 개의 숫자에 대해 ~ 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

비교를 위해 도구 기반 솔루션의 속도가 얼마나 느린 지 알기 위해 C 버전을 컴파일하고 테스트했습니다.

#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

결론

C는 물론 8 초로 가장 빠르지 만 Pypy 솔루션은 약 30 % ~ 11 초의 오버 헤드 만 추가합니다 . 그러나 공정하게 말하면 Pypy는 정확히 표준이 아닙니다. 대부분의 사람들은 CPython 만 설치했는데, 이는 인기있는 Awk 솔루션만큼 정확하게 (22 초) 상당히 느립니다.

표준 툴을 기반으로하는 가장 빠른 솔루션은 Perl (15s)입니다.


2
paste+의 bc접근 방식은 내가, 합계 16 진수 값에 대한 감사를 찾고 있었다 있었는지!
Tomislav Nakic-Alfirevic

1
Rust에서 재미를 위해서만 :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

멋진 답변입니다. nitpick이 아니라 더 오래 실행되는 결과를 포함하기로 결정한 경우 그 대답은 훨씬 더 훌륭
Steven Lu

@StevenLu 나는 대답은 단지 것 느꼈다 이상 때문에 덜 멋진 (단어를 사용하는). 그러나 나는이 느낌을 모든 사람이 공유 할 필요는 없다는 것을 이해할 수있다 :)
Alfe

다음 : numba + parallelisation
리트

17

일반 배쉬 원 라이너

$ cat > /tmp/test
1 
2 
3 
4 
5
^D

$ echo $(( $(cat /tmp/test | tr "\n" "+" ) 0 ))

7
고양이 필요 없음 : echo $(( $( tr "\n" "+" < /tmp/test) 0 ))
agc

2
tr정확히 "평범한 배쉬"/ nitpick이 아닙니다
Benjamin W.

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
그것은 바보입니다 : stackoverflow.com/questions/450799/…
jfs

11

다음은 bash에서 작동합니다.

I=0

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

echo $I

1
파일이 임의로 클 수있는 경우 명령 확장을주의해서 사용해야합니다. numbers.txt가 10MB이면 cat numbers.txt문제가 발생합니다.
Giacomo

1
그러나 실제로 (여기서 더 나은 해결책이 아니라면) 실제로 그 문제가 발생할 때까지 이것을 사용합니다.
Francisco Canedo

11

num-utils를 사용할 수 있지만 필요한만큼 과도 할 수 있습니다. 이것은 쉘에서 숫자를 조작하기위한 일련의 프로그램이며, 물론 그것들을 더하는 것을 포함하여 몇 가지 멋진 일을 할 수 있습니다. 조금 오래되었지만 여전히 작동하며 더 많은 일을 해야하는 경우 유용 할 수 있습니다.

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가 영리한 문자열 붙여 넣기가 아니라 멋진 의미 론적 인 척하는 것을 좋아합니다.)
hobbs

2
예, 설명해주십시오 :) (저는 Perl typea 사람이 아닙니다.)
Jens

1
"perl -MO = Deparse -lpe '$ c + = $ _} {$ _ = $ c'"를 실행하고 출력을 살펴보십시오. 기본적으로 -l은 개행과 입력 및 출력 분리자를 모두 사용하고 -p는 각 행을 인쇄합니다. 그러나 '-p'를 수행하기 위해 perl은 먼저 보일러 플레이트 (-MO = Deparse)가 표시하지만 대신 대체하고 컴파일합니다. 따라서 '} {'부분으로 추가 블록을 삽입하여 각 줄에 인쇄하지 않고 맨 끝에 인쇄하도록 속일 수 있습니다.
Nym

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

왜 두 개의 ((괄호가 ))있습니까?
Atcold

고양이 때문에 순수한 배쉬가 아닙니다. 고양이를 다음과 같이 대체하여 순수 배쉬로 $(< numbers.txt)
만드세요


6

대체 순수 Perl, 읽기 쉬운 패키지 또는 옵션이 필요하지 않습니다.

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

또는 조금 더 짧습니다 : perl -e 'map {$ x + = $ _} <>; $ x 'infile.txt 인쇄
Avi Tevet

1000 만 개의 숫자를 입력하는 데 필요한 메모리는 거의 2GB입니다.
Amit Naidu

6

루비 애호가들에게

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

5

제출을 피할 수 없습니다 :

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

여기에서 찾을 수 있습니다 :
가장 정밀한 유닉스 쉘 원 라이너는 임의의 정밀도의 숫자 목록을 합산합니까?

다음은 awk, bc 및 친구들에 비해 특별한 장점입니다.

  • 버퍼링에 의존하지 않으므로 실제로 큰 입력으로 질식하지 않습니다.
  • 그것은 특정 정밀도 또는 그 물질 한계에 대한 정수 크기를 암시하지 않습니다.
  • 부동 소수점 숫자를 추가해야하는 경우 다른 코드가 필요하지 않습니다.

답변에 질문과 관련된 코드를 포함시키고 링크를 참조하지 마십시오
Ibo

5

GNU 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

Sebastian은 하나의 라이너 스크립트를 지적했습니다.

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

python -c "fileinput 가져 오기 입력에서; print sum (map (int, input ()))"numbers.txt
jfs

2
고양이 남용, 파일에서 stdin을 리디렉션 : python -c "..."<numbers.txt
Giacomo

2
@rjack : cat은 스크립트가 stdin과 argv []의 파일 ( while(<>)Perl 처럼 ) 모두에서 작동 함을 보여줍니다 . 입력이 파일에 있으면 '<'는 필요하지 않습니다.
jfs

2
그러나 < numbers.txt그것이 stdin 에서뿐만 아니라 작동한다는 것을 보여줍니다 cat numbers.txt |. 그리고 나쁜 습관을 가르치지 않습니다.
Xiong Chiamiov

3
$ 고양이 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

그러나이 파일은 파일을 비방하므로 큰 파일에는 사용하지 않는 것이 좋습니다. slurping을 피하는 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

C (단순화되지 않음)

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)

나는 의견을 찬성해야했다. 대답에는 아무런 문제가 없습니다. 꽤 좋습니다. 그러나 의견이 답을 훌륭하게 만든다는 것을 보여주기 위해 의견을 찬성했습니다.
bballdave025

3

백틱 ( "`")의 가독성을 사전에 사과하지만, bash 이외의 쉘에서 작동하므로 붙여 넣기가 더 쉽습니다. 그것을 받아들이는 쉘을 사용한다면, $ (command ...) 형식은`command ...`보다 훨씬 더 읽기 쉽고 (따라서 디버깅 가능하다), 당신의 정신을 자유롭게 수정하십시오.

bashrc에는 awk를 사용하여 여러 간단한 수학 항목을 계산하는 간단한 함수가 있습니다.

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

이것은 +,-, *, /, ^, %, sqrt, sin, cos, 괄호를 사용할 것입니다 ... (그리고 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// /+}`

btw 데스크탑에서 빠른 작업을 수행 해야하는 경우 다음을 사용합니다.

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

2
어떤 종류의 고대 껍질을 사용하고 $()있습니까?
nyuszika7 시간
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.