Saya memiliki 100 juta baris dalam file saya.
Setiap baris hanya memiliki satu kolom.
misalnya
aaaaa
bb
cc
ddddddd
ee
Saya ingin mendaftar jumlah karakter
Seperti ini
2 character words - 3
5 character words - 1
7 character words - 1
dll.
Apakah ada cara mudah untuk melakukan ini di terminal?
text-processing
Giri
sumber
sumber
Jawaban:
awk
Filter pertama hanya akan mencetak panjang setiap baris dalam file yang dipanggilfile
. Saya berasumsi bahwa file ini mengandung satu kata per baris.The
sort -n
(mengurutkan garis dari output secaraawk
numerik dalam urutan menaik) danuniq -c
(menghitung berapa kali setiap baris muncul secara berurutan) kemudian akan membuat output berikut dari itu untuk data yang diberikan:Ini kemudian diuraikan oleh
awk
skrip kedua yang menafsirkan setiap baris sebagai "X jumlah baris yang memiliki karakter Y" dan menghasilkan output yang diinginkan.Solusi alternatif adalah melakukan semuanya dalam
awk
dan menjaga jumlah panjang dalam array. Ini adalah tradeoff antara efisiensi, keterbacaan / kemudahan pemahaman (dan karenanya pemeliharaan) solusi mana yang "terbaik".Solusi alternatif:
sumber
Cara lain untuk melakukan semuanya
awk
sendirianwords[length()]++
gunakan panjang jalur input sebagai kunci untuk menghemat penghitunganEND{for(k in words)print k " character words - " words[k]}
setelah semua baris diproses, cetak konten array dalam format yang diinginkanPerbandingan kinerja, angka yang dipilih adalah yang terbaik dari dua kali proses
Jika file hanya memiliki karakter ASCII,
Tidak yakin mengapa waktu untuk
perl
tidak banyak berubah, mungkin pengodean harus diatur dengan cara lainsumber
length
tanpa()
bekerja dengan baik di sini, jadi mungkin berlebihan untuk menambahkan kawat gigi. Saya menggunakan GNU awk.In older versions of awk, the length() function could be called without any parentheses. Doing so is considered poor practice, although the 2008 POSIX standard explicitly allows it, to support historical practice. For programs to be maximally portable, always supply the parentheses
Berikut ini adalah yang
perl
setara (dengan - opsional - urutkan):sumber
{$a<=>$b}
setelahsort
akan memperbaikinya. Atau, seseorang dapat menggunakan array normal dengan tombol numerik dan lewati saja sembarang tombol yang nilainya nol / tidak terdefinisi.Alternatif satu panggilan ke GNU awk, menggunakan printf :
Algoritma inti hanya mengumpulkan jumlah karakter dalam array. Bagian akhir mencetak jumlah yang dikumpulkan yang diformat dengan printf.
Cepat, sederhana, satu panggilan tunggal untuk awk.
Lebih tepatnya: lebih banyak memori digunakan untuk menyimpan array.
Tetapi tidak ada jenis yang disebut (indeks array numerik diatur untuk selalu dilalui diurutkan ke atas dengan PROCINFO), dan hanya satu program eksternal:,
awk
bukan beberapa.sumber
for in
mungkin terjadi untuk memberikan indeks array numerik dalam urutan numerik setidaknya untuk beberapa nilai atau dalam beberapa implementasi awk, tetapi itu tidak diperlukan, tidak tradisional, dan jelas tidak universal. Itu sering terjadi untuk set kecil seperti 2 atau 3 atau mungkin 4; coba 10 atau 20 pada setiap awk Anda memiliki akses ke (tanpa PROCINFO atau WHINY_USERS di gawk) dan saya yakin $ 50 setidaknya satu kasus tidak diurutkan.@ind_str_asc
mengurutkan sebagai string, yang akan benar untuk angka hanya jika mereka semua satu digit (seperti contoh Anda); gunakan@ind_num_asc
jika (ada) nilai bisa 10 atau lebih. Dan meskipun itu kurang masalah sekarang daripada dulu, fitur ini hanya melongo 4,0 .