답변:
로 awk
:
awk '{total += $0; $0 = total}1'
$0
현재 줄입니다. 따라서 각 줄에 대해을 추가 total
하고 줄을 new로 설정 total
한 후 후행 1
은 어색한 바로 가기입니다. 모든 실제 조건에 대해 현재 줄을 인쇄하고 1
조건이 true로 평가됩니다.
print
를 사용할 수 있습니까 ?
print total}
대신$0 = total}1
{print(total += $0)}
파이썬 스크립트에서 :
#!/usr/bin/env python3
import sys
f = sys.argv[1]; out = sys.argv[2]
n = 0
with open(out, "wt") as wr:
with open(f) as read:
for l in read:
n = n + int(l); wr.write(str(n)+"\n")
add_last.py
소스 파일과 대상 출력 파일을 인수로 사용하여 실행하십시오.
python3 /path/to/add_last.py <input_file> <output_file>
코드는 읽기 쉽지만 자세하게 설명하면 다음과 같습니다.
결과 쓰기를위한 출력 파일 열기
with open(out, "wt") as wr:
한 줄 에 읽을 수 있도록 열린 입력 파일
with open(f) as read:
for l in read:
줄을 읽고 새 줄의 값을 총계에 추가하십시오.
n = n + int(l)
결과를 출력 파일에 작성하십시오.
wr.write(str(n)+"\n")
재미로
$ sed 'a+p' file | dc -e0 -
3
7
12
20
이것에 의해 작동 ppending 받는 결과를 통과 한 후 각각의 입력 라인에, 그리고 계산기 곳+p
dc
+ Pops two values off the stack, adds them, and pushes the result.
The precision of the result is determined only by the values of
the arguments, and is enough to be exact.
그때
p Prints the value on the top of the stack, without altering the
stack. A newline is printed after the value.
-e0
인수 푸시 0
위에 dc
스택 합계를 초기화한다.
real 0m4.234s
한 줄에 하나씩 표준 입력에 주어진 정수의 부분 합을 인쇄하려면 :
#!/usr/bin/env python3
import sys
partial_sum = 0
for n in map(int, sys.stdin):
partial_sum += n
print(partial_sum)
실행 가능한 예 .
어떤 이유로 명령이 너무 느리면; C 프로그램을 사용할 수 있습니다 :
#include <stdint.h>
#include <ctype.h>
#include <stdio.h>
int main(void)
{
uintmax_t cumsum = 0, n = 0;
for (int c = EOF; (c = getchar()) != EOF; ) {
if (isdigit(c))
n = n * 10 + (c - '0');
else if (n) { // complete number
cumsum += n;
printf("%ju\n", cumsum);
n = 0;
}
}
if (n)
printf("%ju\n", cumsum + n);
return feof(stdin) ? 0 : 1;
}
빌드하고 실행하려면 다음을 입력하십시오.
$ cc cumsum.c -o cumsum
$ ./cumsum < input > output
실행 가능한 예 .
UINTMAX_MAX
입니다 18446744073709551615
.
C 코드는 다음에 의해 생성 된 입력 파일에 대해 내 컴퓨터의 awk 명령보다 몇 배 빠릅니다.
#!/usr/bin/env python3
import numpy.random
print(*numpy.random.random_integers(100, size=2000000), sep='\n')
아마도 다음과 같은 것을 원할 것입니다 :
sort -n <filename> | uniq -c | awk 'BEGIN{print "Number\tFrequency"}{print $2"\t"$1}'
명령 설명 :
sort -n <filename> | uniq -c
입력을 정렬하고 빈도 표를 반환합니다.| awk 'BEGIN{print "Number\tFrequency"}{print $2"\t"$1}'
출력을 더 좋은 형식으로 바꿉니다.예 :
입력 파일 list.txt
:
4
5
3
4
4
2
3
4
5
명령 :
$ sort -n list.txt | uniq -c | awk 'BEGIN{print "Number\tFrequency"}{print $2"\t"$1}'
Number Frequency
2 1
3 2
4 4
5 2
이 작업은 vim에서 수행 할 수 있습니다. 파일을 열고 다음 키 입력을 입력하십시오.
qaqqayiwj@"<C-a>@aq@a:wq<cr>
참고 <C-a>
실제로 CTRL-A, 그리고 <cr>
이다 캐리지 리턴 , 즉 버튼을 입력합니다.
작동 방식은 다음과 같습니다. 먼저, 우리는 처음으로 부작용이 없도록 레지스터 'a'를 지우고 싶습니다. 이것은 간단 qaq
합니다. 그런 다음 우리는 다음을 수행합니다.
qa " Start recording keystrokes into register 'a'
yiw " Yank this current number
j " Move down one line. This will break the loop on the last line
@" " Run the number we yanked as if it was typed, and then
<C-a> " increment the number under the cursor *n* times
@a " Call macro 'a'. While recording this will do nothing
q " Stop recording
@a " Call macro 'a', which will call itself creating a loop
이 재귀 매크로가 실행되면 :wq<cr>
저장하고 종료하기 만하면 됩니다.
펄 원 라이너 :
$ perl -lne 'print $sum+=$_' input.txt
3
7
12
20
250 만 줄의 숫자로 처리하는 데 약 6.6 초가 걸립니다.
$ time perl -lne 'print $sum+=$_' large_input.txt > output.txt
0m06.64s real 0m05.42s user 0m00.09s system
$ wc -l large_input.txt
2500000 large_input.txt
real 0m0.908s
꽤 좋습니다.
간단한 배쉬 원 라이너 :
x=0 ; while read n ; do x=$((x+n)) ; echo $x ; done < INPUT_FILE
x
현재 줄 이상에서 모든 숫자의 누적 합계입니다.
n
현재 줄의 숫자입니다.
우리는 모든 줄 n
을 반복 INPUT_FILE
하고 숫자 값을 변수에 추가하고 x
각 반복 동안 그 합계를 인쇄합니다.
Bash는 여기에서 조금 느리다. 출력을 콘솔에 출력하지 않고 2 백만 개의 항목이있는 파일에 대해 약 20-30 초가 실행될 것으로 예상 할 수 있습니다 (사용하는 방법에 관계없이 더 느리다).
@steeldriver의 답변과 비슷하지만 bc
대신 약간 덜 신비 합니다.
sed 's/.*/a+=&;a/' input | bc
bc
(및 dc
) 의 좋은 점 은 임의의 정밀 계산기이므로 오버플로하거나 정수보다 정밀도가 부족하지 않다는 것입니다.
sed
표현식 입력 변환 :
a+=3;a
a+=4;a
a+=5;a
a+=8;a
그런 다음에 의해 평가됩니다 bc
. a
BC 변수는 자동으로 초기화 각 라인 단위로 0이 a
, 다음 명시 적으로 인쇄합니다.
real 0m5.642s
130 만 줄에 sed는 이것에 정말 느립니다.