Saya memiliki file teks dengan 2 juta baris. Setiap baris memiliki bilangan bulat positif. Saya mencoba untuk membentuk semacam tabel frekuensi hal.
File input:
3
4
5
8
Output harus:
3
7
12
20
Bagaimana cara saya melakukan ini?
command-line
text-processing
Monty Harder
sumber
sumber
Jawaban:
Dengan
awk
:$0
adalah baris saat ini. Jadi, untuk setiap baris, saya menambahkannya ketotal
, setel baris ke yang barutotal
, dan kemudian trailing1
adalah jalan pintas awk - ini mencetak baris saat ini untuk setiap kondisi yang benar, dan1
ketika suatu kondisi mengevaluasi ke true.sumber
print
itu digunakan juga?print total}
bukannya$0 = total}1
{print(total += $0)}
Dalam skrip python:
Menggunakan
add_last.py
Jalankan dengan file sumber dan file output yang ditargetkan sebagai argumen:
Penjelasan
Kode ini agak mudah dibaca, tetapi secara detail:
Buka file output untuk menulis hasil
Buka file input untuk dibaca per baris
Baca baris, tambahkan nilai baris baru ke total:
Tulis hasilnya ke file output:
sumber
Hanya untuk bersenang-senang
Ini bekerja dengan sebuah ppending
+p
untuk setiap baris dari input, dan kemudian melewati hasilnya kedc
kalkulator manakemudian
The
-e0
dorongan argumen0
kedc
tumpukan untuk menginisialisasi jumlahnya.sumber
real 0m4.234s
Di Bash:
sumber
real 0m53.116s
Untuk mencetak sebagian jumlah bilangan bulat yang diberikan pada input standar satu per baris:
Contoh runnable .
Jika karena alasan tertentu perintahnya terlalu lambat; Anda bisa menggunakan program C:
Untuk membangun dan menjalankannya, ketik:
Contoh runnable .
UINTMAX_MAX
adalah18446744073709551615
.Kode C beberapa kali lebih cepat daripada perintah awk pada mesin saya untuk file input yang dihasilkan oleh:
sumber
accumulate()
itertoolAnda mungkin menginginkan sesuatu seperti ini:
Penjelasan perintah:
sort -n <filename> | uniq -c
mengurutkan input dan mengembalikan tabel frekuensi| awk 'BEGIN{print "Number\tFrequency"}{print $2"\t"$1}'
mengubah ooutput menjadi Format yang lebih bagusContoh:
File Input
list.txt
:Perintah:
sumber
Anda dapat melakukan ini di vim. Buka file dan ketik penekanan tombol berikut:
Perhatikan bahwa
<C-a>
sebenarnya ctrl-a, dan<cr>
merupakan carriage return , yaitu tombol enter.Begini cara kerjanya. Pertama, kami ingin menghapus register 'a' sehingga tidak memiliki efek samping pada saat pertama kali melalui. Ini sederhana
qaq
. Kemudian kita lakukan hal berikut:Setelah makro rekursif ini selesai berjalan, kami cukup memanggil
:wq<cr>
untuk menyimpan dan keluar.sumber
Perl one-liner:
Dengan 2,5 juta baris angka, dibutuhkan proses sekitar 6,6 detik:
sumber
real 0m0.908s
cukup bagusBash one-liner sederhana:
x
adalah jumlah terakumulasi dari semua angka dari baris saat ini dan di atas.n
adalah nomor di baris saat ini.Kami loop atas semua baris
n
dariINPUT_FILE
dan menambah nilai numerik mereka untuk variabel kamix
dan mencetak jumlah itu selama setiap iterasi.Namun, Bash agak lambat di sini, Anda bisa berharap ini berjalan sekitar 20-30 detik untuk file dengan 2 juta entri, tanpa mencetak output ke konsol (yang bahkan lebih lambat, tidak tergantung pada metode yang Anda gunakan).
sumber
Mirip dengan jawaban @ steeldriver, tetapi dengan sedikit lebih misterius
bc
:Yang menyenangkan tentang
bc
(dandc
) adalah bahwa mereka adalah kalkulator presisi yang sewenang-wenang, jadi tidak akan pernah meluap atau mengalami kekurangan presisi atas bilangan bulat.The
sed
ekspresi mengubah input ke:Ini kemudian dievaluasi oleh
bc
. Thea
variabel bc adalah auto-dijalankan ke 0. Setiap kenaikan garisa
, maka secara eksplisit mencetaknya.sumber
real 0m5.642s
pada 1,3 juta baris. Sed sangat lambat dalam hal ini.