Saya mencari perintah yang akan menerima (sebagai input) beberapa baris teks, setiap baris berisi bilangan bulat tunggal, dan menampilkan jumlah bilangan bulat ini.
Sebagai sedikit latar belakang, saya memiliki file log yang mencakup pengukuran waktu. Melalui grepping untuk baris yang relevan dan sedikit sed
memformat ulang saya bisa daftar semua timing dalam file itu. Saya ingin menghitung totalnya. Saya dapat menyalurkan output antara ini ke perintah apa saja untuk melakukan penjumlahan akhir. Saya selalu menggunakan expr
di masa lalu, tetapi kecuali itu berjalan dalam mode RPN saya tidak berpikir itu akan mengatasi ini (dan bahkan kemudian itu akan sulit).
Bagaimana saya bisa mendapatkan penjumlahan bilangan bulat?
Jawaban:
Sedikit canggung harus melakukannya?
Catatan: beberapa versi awk memiliki beberapa perilaku aneh jika Anda akan menambahkan sesuatu yang melebihi 2 ^ 31 (2147483647). Lihat komentar untuk latar belakang lebih lanjut. Satu saran adalah menggunakan
printf
daripadaprint
:sumber
ls $@ | xargs -i pdftk {} dump_data | grep NumberOfPages | awk '{s+=$2} END {print s}'
awk '{s+=$1} END {printf "%.0f", s}' mydatafile
sebagai gantinya.Rekatkan biasanya menggabungkan baris beberapa file, tetapi juga dapat digunakan untuk mengubah setiap baris file menjadi satu baris. Bendera pembatas memungkinkan Anda untuk melewatkan persamaan tipe x + x ke bc.
Atau, saat pemipaan dari stdin,
sumber
paste
dapat menggunakan tanda hubung-
sebagai nama file - yang akan memungkinkan Anda untuk menyalurkan angka-angka dari output perintah ke dalam output standar pasta tanpa perlu membuat file terlebih dahulu:<commands> | paste -sd+ - | bc
-
. (Ini berguna jika Anda ingin menggabungkan file dengan stdin).Versi satu-baris dalam Python:
sumber
python -c"import sys; print(sum(map(int, sys.stdin)))"
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))"
import sys; print(sum(int(''.join(c for c in l if c.isdigit())) for l in sys.stdin))
Saya akan menaruh PERINGATAN besar pada solusi yang disetujui secara umum:
itu karena dalam bentuk ini awk menggunakan representasi integer bertanda 32 bit: ia akan melimpah untuk jumlah yang melebihi 2147483647 (yaitu, 2 ^ 31).
Jawaban yang lebih umum (untuk menjumlahkan bilangan bulat) adalah:
sumber
echo -e "2147483647 \n 100" |awk '{s+=$1}END{print s}'
shows2147483747
echo 999999999999999999 | awk '{s+=$1} END {printf "%.0f\n", s}'
menghasilkan1000000000000000000
Pesta polos:
sumber
num
didefinisikan? Saya percaya entah bagaimana itu terhubung ke< numbers.txt
ekspresi, tetapi tidak jelas caranya.Perhatikan bahwa angka negatif yang diawali dengan tanda minus harus diterjemahkan untuk
dc
, karena menggunakan_
awalan daripada-
awalan untuk itu. Misalnya melaluitr '-' '_' | dc -f- -e '...'
.Sunting: Karena jawaban ini mendapatkan begitu banyak suara "untuk ketidakjelasan", berikut adalah penjelasan terperinci:
Ekspresi
[+z1<r]srz1<rp
melakukan hal berikut :Sebagai pseudo-code:
Untuk benar-benar memahami kesederhanaan dan kekuatan
dc
, berikut ini adalah skrip Python yang berfungsi yang mengimplementasikan beberapa perintah daridc
dan mengeksekusi versi Python dari perintah di atas:sumber
(echo "0"; sed 's/$/ +/' inp; echo 'pq')|dc
.dc -e '0 0 [+?z1<m]dsmxp'
. Jadi kami tidak menyimpan semua angka pada tumpukan sebelum memproses tetapi membaca dan memprosesnya satu per satu (lebih tepatnya, baris demi baris, karena satu baris dapat berisi beberapa angka). Perhatikan bahwa baris kosong dapat mengakhiri urutan input.sed
substitusi dapat dihilangkan, karenadc
tidak peduli tentang ruang antara argumen dan operator.(echo "0"; sed 's/$/+/' inputFile; echo 'pq')|dc
Dengan jq :
sumber
Pesta murni dan pendek.
sumber
f=$(<numbers.txt)
.f=$(cat); echo $(( ${f//$'\n'/+} ))
skrip, maka Anda dapat menyalurkan apa saja ke skrip tersebut atau menjalankannya tanpa argumen untuk input stdin interaktif (diakhiri dengan Control-D).<numbers.txt
merupakan peningkatan, tetapi, secara keseluruhan, solusi ini hanya efisien untuk file input kecil; misalnya, dengan file 1.000 baris input,awk
solusi yang diterima sekitar 20 kali lebih cepat pada mesin saya - dan juga mengkonsumsi lebih sedikit memori, karena file tidak dibaca sekaligus.sumber
Lima belas sen saya:
Contoh:
sumber
grep -v '^$'
. Terima kasih!Saya sudah melakukan patokan cepat pada jawaban yang ada
lua
ataurocket
),Saya selalu menambahkan angka 1 hingga 100 juta yang dapat dilakukan pada komputer saya dalam waktu kurang dari satu menit untuk beberapa solusi.
Inilah hasilnya:
Python
Awk
Tempel & Bc
Ini kehabisan memori pada mesin saya. Ini berfungsi untuk setengah ukuran input (angka 50 juta):
Jadi saya kira itu akan mengambil ~ 35 untuk 100 juta angka.
Perl
Rubi
C
Hanya untuk perbandingan, saya menyusun versi C dan menguji ini juga, hanya untuk mengetahui seberapa jauh lebih lambat solusi berbasis alat.
Kesimpulan
C tentu saja tercepat dengan 8s, tetapi solusi Pypy hanya menambahkan sedikit overhead sekitar 30% menjadi 11s . Tapi, agar adil, Pypy tidak sepenuhnya standar. Kebanyakan orang hanya menginstal CPython yang jauh lebih lambat (22-an), persis secepat solusi populer Awk.
Solusi tercepat berdasarkan pada alat standar adalah Perl (15s).
sumber
paste
+bc
Pendekatan itu hanya apa yang saya cari untuk jumlah nilai hex, terima kasih!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); }
Bash polos satu liner
sumber
echo $(( $( tr "\n" "+" < /tmp/test) 0 ))
tr
bukan "Bash biasa" / nitpickSolusi BASH, jika Anda ingin menjadikan ini sebagai perintah (mis. Jika Anda harus sering melakukan ini):
Kemudian penggunaan:
sumber
Saya pikir AWK adalah apa yang Anda cari:
Anda dapat menggunakan perintah ini baik dengan meneruskan daftar angka melalui input standar atau dengan mengirimkan file yang berisi angka sebagai parameter.
sumber
Berikut ini berfungsi di bash:
sumber
cat numbers.txt
langkah itu akan bermasalah.Anda dapat menggunakan num-utils, meskipun mungkin terlalu banyak untuk apa yang Anda butuhkan. Ini adalah sekumpulan program untuk memanipulasi angka dalam shell, dan dapat melakukan beberapa hal bagus, termasuk tentu saja, menambahkannya. Agak ketinggalan zaman, tetapi masih berfungsi dan dapat berguna jika Anda perlu melakukan sesuatu yang lebih.
http://suso.suso.org/programs/num-utils/
sumber
numsum numbers.txt
.Saya menyadari ini adalah pertanyaan lama, tetapi saya cukup menyukai solusi ini untuk membagikannya.
Jika ada minat, saya akan menjelaskan cara kerjanya.
sumber
Bash murni dan dalam satu baris :-)
sumber
((
tanda kurung))
?$(< numbers.txt)
sumber
Alternatif Perl murni, cukup mudah dibaca, tidak ada paket atau opsi yang diperlukan:
sumber
Untuk Pecinta Ruby
sumber
Tidak dapat menghindari mengirimkan ini:
Ditemukan di sini:
Kebanyakan unix shell satu-liner yang elegan untuk menjumlahkan daftar jumlah presisi yang sewenang-wenang?
Dan berikut ini adalah kelebihan khusus dari awk, bc dan teman-teman:
sumber
Menggunakan utilisasi GNU
datamash
:Keluaran:
Jika input data tidak teratur, dengan spasi dan tab di tempat ganjil, ini dapat membingungkan
datamash
, maka gunakan-W
sakelar:... atau gunakan
tr
untuk membersihkan spasi:sumber
Versi saya:
sumber
seq -s+ -5 10 | bc
Anda bisa melakukannya dengan python, jika Anda merasa nyaman:
Tidak diuji, cukup diketik:
Sebastian menunjukkan naskah satu liner:
sumber
cat
digunakan untuk menunjukkan bahwa skrip berfungsi baik untuk stdin dan untuk file dalam argv [] (sepertiwhile(<>)
di Perl). Jika input Anda ada dalam file maka '<' tidak perlu.< numbers.txt
menunjukkan bahwa ia bekerja pada stdin sama baiknyacat numbers.txt |
. Dan itu tidak mengajarkan kebiasaan buruk.Atau, Anda bisa mengetikkan angka di baris perintah:
Namun, yang satu ini menyeruput file tersebut sehingga itu bukan ide yang baik untuk digunakan pada file besar. Lihat j_random_hacker jawaban yang menghindari menghirup.
sumber
Berikut ini harus berfungsi (dengan asumsi nomor Anda adalah bidang kedua pada setiap baris).
sumber
One-liner di Racket:
sumber
C (tidak disederhanakan)
sumber
Permintaan maaf sebelumnya untuk keterbacaan backticks ("` "), tetapi ini bekerja dalam cangkang selain bash dan karenanya lebih mudah ditempel. Jika Anda menggunakan shell yang menerimanya, format $ (command ...) jauh lebih mudah dibaca (dan dengan demikian dapat ditiadakan) daripada `command ...` jadi jangan ragu untuk memodifikasi kewarasan Anda.
Saya memiliki fungsi sederhana di bashrc saya yang akan menggunakan awk untuk menghitung sejumlah item matematika sederhana
Ini akan melakukan +, -, *, /, ^,%, sqrt, sin, cos, kurung .... (dan lebih banyak tergantung pada versi awk Anda) ... Anda bahkan dapat menikmati printf dan memformat floating point output, tapi ini semua biasanya saya butuhkan
untuk pertanyaan khusus ini, saya cukup melakukan ini untuk setiap baris:
jadi blok kode untuk menjumlahkan setiap baris akan terlihat seperti ini:
Itu jika Anda hanya ingin menjumlahkannya baris demi baris. Namun untuk total setiap angka dalam datafile
btw jika saya perlu melakukan sesuatu dengan cepat di desktop, saya menggunakan ini:
sumber
$()
?