파일의 모든 숫자를 빠르게 합산하려면 어떻게해야합니까?


16

각 줄에는 한 열에 텍스트와 숫자가 포함됩니다. 각 행의 숫자 합계를 계산해야합니다. 어떻게해야합니까? 고마워

example.log에는 다음이 포함됩니다.

time=31sec
time=192sec
time=18sec
time=543sec

답은 784 여야합니다


이 방법을 시도했습니다 awk '{sum + = $ 1}; END {print sum} 'example.log 그러나 행 번호에만 해당
Jack

2
에서 동일한 질문 거의가 스택 오버플로 : 어떻게 신속하게 파일에 모든 숫자의 합계 수는? . 교차 사이트 복제 시간이 있을까요?
fedorqui

답변:


18

귀하의 경우 grep지원 -o옵션, 당신은 시도 할 수 있습니다 :

$ grep -o '[[:digit:]]*' file | paste -sd+ - | bc
784

POSIXly :

$ printf %d\\n "$(( $(tr -cs 0-9 '[\n*]' <file | paste -sd+ -) ))"
784

16

GNU 최신 버전 (4.x) awk:

awk 'BEGIN {FPAT="[0-9]+"}{s+=$1}END{print s}'

다른 awk시도로 :

awk -F '[a-z=]*' '{s+=$2}END{print s}'

4
당신은 필요한 s+0경우 s비어가 인쇄됩니다 0대신 빈의.
cuonglm

설명해 드리겠습니다. - s비워 질 수있는 경우는 한 가지뿐입니다 . 입력 데이터에 없는 경우 (즉, 입력전혀없는 경우 ) 이 경우 가능한 두 가지 동작이 있습니다. 1) 입력 없음 => 출력 없음 또는 2) 항상 0 인 경우 항상 출력합니다. 둘 다 응용 프로그램 컨텍스트에 따라 적절한 옵션입니다. 는 +0) 옵션 2를 해결한다. 옵션 1)을 해결하려면 오히려 작성해야합니다 END {if(s) print s}. 따라서 질문에 의해 지정 될 때까지 두 가지 옵션 (데이터가없는 경우)을 가정하는 것은 의미가 없습니다.
Janis

10
awk -F= '{sum+=$2};END{print sum}'

2
우리는 긴 형식의 답변을 선호합니다. 이것이 어떻게 작동하는지 자세히 설명해 주시겠습니까?
slm

2
@ slm, 그 대답은 여기의 다른 대답보다 더 많거나 덜 장황하지 않으며 자체 설명입니다. 또한 같은 입력 작업의 장점이있다time=1.4e5sec
스테판 Chazelas가

@ StéphaneChazelas-동의했지만 이것은 새로운 사용자이며 사용자가 한 줄 이상의 답변을 제공하도록 권장합니다. 작동 방식을 설명하는 약간의 텍스트는 코드보다 훨씬 더 강력한 답변을 제공합니다.
slm

4
@ slm, 이것은 기술적 인 관점에서 가장 좋은 답변 중 하나를 가진 새로운 사용자이며 두 개의 downvotes와 부정적인 의견을 얻습니다. 매우 따뜻한 환영은 아닙니다.
Stéphane Chazelas

1
awk의 POSIX 구문 인 @TomFenech는 이러한 패턴 / 액션 항목을 ";"으로 구분해야합니다. 또는 "newline"이므로이 ";"없이 실패한 경우 awk 구현을 찾을 수 있습니다.
Stéphane Chazelas

7

또 다른 GNU awk하나 :

awk -v RS='[0-9]+' '{n+=RT};END{print n}'

perl하나

perl -lne'$n+=$_ for/\d+/g}{print$n'

POSIX 하나 :

tr -cs 0-9 '[\n*]' | grep . | paste -sd + - | bc

6
sed 's/=/ /' file | awk '{ sum+=$2 } END { print sum}'

굉장한 대답이지만 필요는 없습니다 sed.awk --field-separator = '{ sum+=$2 } END { print sum}' data.dat
user1717828

@ user1717828 : 당신은 오히려 (호환성 짧은, 그리고!)을 사용해야 -F'='대신--field-separator =
올리비에 Dulac

@OlivierDulac, 이상한, 내 man awk유일한 제공 -F fs--field-separator fs
user1717828

@ user1717828 : -F'='또는 -F '='두 가지 방법으로 -F fs(fs는 "=")입니다. 나는 작은 따옴표를 추가하여 fs가 쉘이 아닌 awk에 의해 올바르게 보이고 해석되도록합니다 (예를 들어 fs가 ';'인 경우 유용)
Olivier Dulac

4

당신은 이것을 시도 할 수 있습니다 :

awk -F"[^0-9]+" '{ sum += $2 } END { print sum+0; }' file

4

모두가 멋진 awk답변 을 게시했습니다 .

@cuonglm의 변형은 다음으로 대체 grep됩니다 sed.

sed 's/[^0-9]//g' example.log | paste -sd'+' - | bc
  1. 그만큼 sed 숫자를 제외한 모든 것을 제거합니다.
  2. 그만큼 paste -sd+ - 명령은 모든 라인을 단일 라인으로 결합합니다
  3. bc표현식을 평가

3

계산기를 사용해야합니다.

{ tr = \ | xargs printf '[%s=]P%d+p' | dc; } <infile 2>/dev/null

네 줄을 인쇄하면 :

time=31
time=223
time=241
time=784

그리고 더 간단하게 :

tr times=c '    + p' <infile |dc

... 인쇄 ...

31
223
241
784

속도가 당신이 dc추구하는 것이라면 원하는 것입니다. 전통적으로 그것은 bc컴파일러였으며 여전히 많은 시스템을위한 것입니다.


내 측정 에 따르면 : 그것은 수식을 생성하기 위해 얼마나 많은 작업을 수행해야하는지에 따라 달라집니다
glenn jackman

@glennjackman-측정 값에 dc내가 알 수있는만큼 가까이 포함 되어 있지 않습니다 . 무슨 소리 야?
mikeserv 2016 년

그건 그렇고, perl표준 유닉스 툴셋 을 벤치 마크 할 때와 같이 오래된 승무원을 새로운 승무원과 비교할 때 GNU 툴 체인에서 컴파일 된 GNU 툴을 사용하는 것은 실제로 의미가 없습니다. 부정적인 펄의 성능에 영향을 미칠 수 부풀게 모두는 또한모든 사람들 GNU 컴파일 GNU 유틸의. 슬프지만 사실이야. 차이를 정확하게 판단하려면 실제적이고 단순하게 구축 된 간단한 도구 세트가 필요합니다. 예를 들어 musl libs에 대해 정적으로 연결된 가보 도구 모음과 같이 한 도구 / 한 작업 패러다임과 한 도구 / 규칙에 대한 전체 패러다임을 벤치마킹 할 수 있습니다.
mikeserv 2016 년

3

python3을 통해

import re
with open(file) as f:
    m = f.read()
    l = re.findall(r'\d+', m)
    print(sum(map(int, l)))

re.findall문자열 목록을 반환합니다.이 기능은 작동하지 않습니다
iruvar

@ 1_CR 나중에, 잊어 버렸습니다. 바로 확인해보세요.
Avinash Raj

어쩌면 sum(int(e) for e in l)더 pythonic 일 것입니다.
cuonglm

3

순수 배쉬 솔루션 (Bash 3+) :

while IFS= read -r line; do                   # While it reads a line:
    if [[ "$line" =~ [0-9]+ ]]; then      # If the line contains numbers:
        ((counter+=BASH_REMATCH[0]))          # Add the current number to counter
    fi                                    # End if.
done                                  # End loop.

echo "Total number: $counter"         # Print the number.
unset counter                         # Reset counter to 0.

짧은 버전 :

while IFS= read -r l; do [[ "$l" =~ [0-9]+ ]] && ((c+=BASH_REMATCH)); done; echo $c; c=0

1
PS4='$((x+=${time%s*}))' time=0 x=0 sh -x <infile
mikeserv
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.