Misalnya saya punya file 1.txt
, yang berisi:
Moscow
Astana
Tokyo
Ottawa
Saya ingin menghitung jumlah semua char sebagai:
a - 4,
b - 0,
c - 1,
...
z - 0
command-line
bash
text-processing
Set-xx
sumber
sumber
Jawaban:
Anda bisa menggunakan ini:
Bagian ini
sed
menempatkan baris baru setelah setiap karakter. Kemudian kamisort
ouput secara alfabet. Dan pada akhirnyauniq
menghitung jumlah kejadian. The-i
Benderauniq
dapat menghilangkan sebagian jika Anda tidak ingin kasus ketidakpekaan.sumber
sort -k 2
daftar mereka berdasarkan alfanumerik.sed -e $'s/\(.\)/\\1\\\n/g'
(lihat juga stackoverflow.com/a/18410122/179014 )| sort -rnk 1
. Dan jika Anda berurusan dengan file yang sangat besar, seperti saya, Anda bisa mencicipi beberapa ribu baris untuk mendapatkan proksi untuk hitungan aktual:cat 1.txt | shuf -n 10000 | sed 's/\(.\)/\1\n/g' | sort | uniq -ic | sort -rnk 1
Agak terlambat, tetapi untuk menyelesaikan set, pendekatan python lain (3), hasil diurutkan:
Penjelasan
Baca file, lewati spasi dan kembali sebagai "karakter":
Buat seperangkat unik (diurutkan):
Hitung dan cetak kemunculan untuk masing-masing karakter:
Cara Penggunaan
chars_count.py
Jalankan dengan file sebagai argumen oleh:
jika skrip dapat dieksekusi, atau:
jika tidak
sumber
Secara default di awk , F ield S eparator (FS) adalah spasi atau tab . Karena kami ingin menghitung setiap karakter, kami harus mendefinisikan ulang FS menjadi nothing (
FS=""
) untuk membagi setiap karakter dalam baris yang terpisah dan menyimpannya ke dalam array dan pada akhirnya di dalamEND{..}
blok, cetak total kemunculannya dengan perintah awk berikut :Dalam
{for (i=1;i<=NF;i++) a[$i]++} ... FS="" ...
blok kami hanya membagi karakter. Dandalam
END{for (c in a) print c,a[c]}
blok kita mengulang ke arraya
dan mencetak karakter yang disimpan di dalamnyaprint c
dan jumlah kemunculannyaa[c]
sumber
Lakukan
for
perulangan untuk semua karakter yang ingin Anda hitung, dan gunakangrep -io
untuk mendapatkan semua kemunculan karakter dan abaikan case, danwc -l
untuk menghitung instance, dan cetak hasilnya.Seperti ini:
Script menghasilkan ini:
Sunting setelah komentar
Untuk membuat lingkaran untuk semua karakter yang dapat dicetak, Anda dapat melakukan ini:
Ini akan menghitung semua karakter ANSI dari 32 hingga 126 - ini adalah yang paling umum dibaca. Perhatikan bahwa ini tidak menggunakan kasus abaikan.
output dari ini adalah:
sumber
i
dari grep. (dalam pertanyaan Anda, Anda hanya memiliki 3 dalam hasil yang diharapkan)grep
seluruh input berulang kali.Di sini solusi lain (awk) ...
sumber
cat file | awk '...'
: bisa langsung di bilangawk '...' file
.perl
Oneliner berikut akan menghitung. Saya menempatkan regex dalam konteks daftar (untuk mendapatkan jumlah kecocokan) dan memasukkannya ke dalam konteks skalar:sumber
perl -Mfeature=say -e '$a=join("",<>);say join(",\n", map { sprintf("%s - %d", $_, ($d=()=$a=~/$_/gi)); } ("a".."z"))'
Berikut ini solusi menggunakan Python:
Di sini kita telah menggunakan kelas
collections
modulCounter
untuk menghitung jumlah kemunculan setiap karakter, kemudian untuk tujuan pencetakan kita telah menggunakanstring
modul untuk mendapatkan semua huruf kecil dengan variabelstring.lowercase
.Simpan skrip di atas dalam file yang memberikan nama apa pun yang Anda inginkan misalnya
count.py
. Sekarang dari direktori yang sama di mana file disimpan, Anda dapat menjalankanpython count.py
untuk menjalankan file, dari direktori lain menggunakan jalur absolut ke file untuk menjalankannya yaitupython /absolute/path/to/count.py
.sumber
Beberapa waktu yang lalu saya menulis program C untuk melakukan itu, karena saya membutuhkannya untuk melihat file besar dan menghasilkan beberapa statika.
kompilasi dengan (dengan asumsi kode sumber berada di
character-distribution.c
):jalankan dengan:
Jika Anda tidak memiliki kompiler C yang siap, instal GCC:
sumber
Solusi serupa dengan @heemayl, dengan kode yang lebih ketat, yang berfungsi pada Python 2.7 dan Python 3.
Pernyataan pertama,
count = collections.Counter(…)
melakukan semua pekerjaan nyata.fileinput.input()
membaca setiap baris input, yang dapat disalurkan melalui stdin atau sebagai argumen baris perintah.*
membuatnya mempertimbangkan karakter pada suatu waktu daripada garis pada suatu waktu.count = Counter(…)
menghitung kemunculan setiap karakter secara efisien, dalam sekali lintasan, dan menyimpan hasilnya dalamcount
variabel.Baris kedua hanya mencetak hasilnya.
'{} - {}'.format(c, count[c] + count[c.upper()]) for c in string.ascii_lowercase
membuat daftar setiap karakter dan jumlahnya.print(',\n'.join(…))
menempatkannya dalam format yang diinginkan: satu per baris, dipisahkan dengan koma, tetapi tidak ada koma di baris terakhir.sumber
GNU awk 4.1
Jika Anda memiliki versi GNU awk yang lebih lama, Anda dapat menggunakannya
for (c in b) print c, b[c]
.sumber
Inilah jawabannya menggunakan ruby. Hal ini dilakukan dengan mengubah string menjadi daftar unik karakter yang berbeda dan menggunakan metode hitungan pada masing-masing karakter.
sumber