回答:
とawk
:
awk '{total += $0; $0 = total}1'
$0
現在の行です。したがって、各行について、それをに追加しtotal
、行をnewに設定するtotal
と、末尾1
がawkショートカットに1
なります。これは、すべてのtrue条件の現在の行を出力し、条件がtrueと評価されるときに出力します。
print
も使えますか?
print total}
代わりに$0 = total}1
{print(total += $0)}
Pythonスクリプト:
#!/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:
入力ファイルを開いて1行ごとに読み取る
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
バッシュで:
#! /bin/bash
file="YOUR_FILE.txt"
TOTAL=0
while IFS= read -r line
do
TOTAL=$(( TOTAL + line ))
echo $TOTAL
done <"$file"
real 0m53.116s
、ほぼ1分、130万行で:)
標準入力で指定された整数の部分合計を1行に1つずつ出力するには:
#!/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}'
ooutputをより良いフォーマットに変換します例:
入力ファイル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-あり、そして<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ワンライナー:
$ 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
、 けっこういい。
@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はこれに関して本当に遅いです。