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
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
Jawaban:
Anda bisa menggunakan ini:
sed 's/\(.\)/\1\n/g' 1.txt | sort | uniq -ic
4
5 a
1 c
1 k
1 M
1 n
5 o
2 s
4 t
2 w
1 y
Bagian ini sedmenempatkan baris baru setelah setiap karakter. Kemudian kami sortouput secara alfabet. Dan pada akhirnya uniqmenghitung jumlah kejadian. The -iBendera uniqdapat menghilangkan sebagian jika Anda tidak ingin kasus ketidakpekaan.
sort -k 2daftar 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:
#!/usr/bin/env python3
import sys
chars = open(sys.argv[1]).read().strip().replace("\n", "")
[print(c+" -", chars.count(c)) for c in sorted(set([c for c in chars]))]
A - 1
M - 1
O - 1
T - 1
a - 4
c - 1
k - 1
n - 1
o - 4
s - 2
t - 3
w - 2
y - 1
Baca file, lewati spasi dan kembali sebagai "karakter":
chars = open(sys.argv[1]).read().strip().replace("\n", "")Buat seperangkat unik (diurutkan):
sorted(set([c for c in chars]))Hitung dan cetak kemunculan untuk masing-masing karakter:
print(c+" -", chars.count(c)) for c in <uniques>chars_count.pyJalankan dengan file sebagai argumen oleh:
/path/to/chars_count.py </path/to/file>
jika skrip dapat dieksekusi, atau:
python3 /path/to/chars_count.py </path/to/file>
jika tidak
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 dalam END{..}blok, cetak total kemunculannya dengan perintah awk berikut :
$ awk '{for (i=1;i<=NF;i++) a[$i]++} END{for (c in a) print c,a[c]}' FS="" file
A 1
M 1
O 1
T 1
a 4
c 1
k 1
n 1
o 4
s 2
t 3
w 2
y 1
Dalam {for (i=1;i<=NF;i++) a[$i]++} ... FS="" ...blok kami hanya membagi karakter. Dan
dalam END{for (c in a) print c,a[c]}blok kita mengulang ke array adan mencetak karakter yang disimpan di dalamnya print cdan jumlah kemunculannyaa[c]
Lakukan forperulangan untuk semua karakter yang ingin Anda hitung, dan gunakan grep -iountuk mendapatkan semua kemunculan karakter dan abaikan case, dan wc -luntuk menghitung instance, dan cetak hasilnya.
Seperti ini:
#!/bin/bash
filename="1.txt"
for char in {a..z}
do
echo "${char} - `grep -io "${char}" ${filename} | wc -l`,"
done
Script menghasilkan ini:
a - 5,
b - 0,
c - 1,
d - 0,
e - 0,
f - 0,
g - 0,
h - 0,
i - 0,
j - 0,
k - 1,
l - 0,
m - 1,
n - 1,
o - 5,
p - 0,
q - 0,
r - 0,
s - 2,
t - 4,
u - 0,
v - 0,
w - 2,
x - 0,
y - 1,
z - 0,
Sunting setelah komentar
Untuk membuat lingkaran untuk semua karakter yang dapat dicetak, Anda dapat melakukan ini:
#!/bin/bash
filename="a.txt"
for num in {32..126}
do
char=`printf "\x$(printf %x ${num})"`
echo "${char} - `grep -Fo "${char}" ${filename} | wc -l`,"
done
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:
- 0,
! - 0,
" - 0,
# - 0,
$ - 0,
% - 0,
& - 0,
' - 0,
( - 0,
) - 0,
* - 0,
+ - 0,
, - 0,
- - 0,
. - 0,
/ - 0,
0 - 0,
1 - 0,
2 - 0,
3 - 0,
4 - 0,
5 - 0,
6 - 0,
7 - 0,
8 - 0,
9 - 0,
: - 0,
; - 0,
< - 0,
= - 0,
> - 0,
? - 0,
@ - 0,
A - 1,
B - 0,
C - 0,
D - 0,
E - 0,
F - 0,
G - 0,
H - 0,
I - 0,
J - 0,
K - 0,
L - 0,
M - 1,
N - 0,
O - 1,
P - 0,
Q - 0,
R - 0,
S - 0,
T - 1,
U - 0,
V - 0,
W - 0,
X - 0,
Y - 0,
Z - 0,
[ - 0,
\ - 0,
] - 0,
^ - 0,
_ - 0,
` - 0,
a - 4,
b - 0,
c - 1,
d - 0,
e - 0,
f - 0,
g - 0,
h - 0,
i - 0,
j - 0,
k - 1,
l - 0,
m - 0,
n - 1,
o - 4,
p - 0,
q - 0,
r - 0,
s - 2,
t - 3,
u - 0,
v - 0,
w - 2,
x - 0,
y - 1,
z - 0,
{ - 0,
| - 0,
} - 0,
~ - 0,
idari grep. (dalam pertanyaan Anda, Anda hanya memiliki 3 dalam hasil yang diharapkan)
grepseluruh input berulang kali.
Di sini solusi lain (awk) ...
awk '
{ for (indx=length($0); indx >= 1; --indx)
++chars[tolower(substr($0, indx, 1))]
}
END { for (c in chars) print c, chars[c]; }
' 1.txt | sort
cat file | awk '...': bisa langsung di bilang awk '...' file.
perlOneliner berikut akan menghitung. Saya menempatkan regex dalam konteks daftar (untuk mendapatkan jumlah kecocokan) dan memasukkannya ke dalam konteks skalar:
$ perl -e '$a=join("",<>);for("a".."z"){$d=()=$a=~/$_/gi;print"$_ - $d,\n"}' 1.txt
a - 5,
b - 0,
c - 1,
d - 0,
e - 0,
f - 0,
g - 0,
h - 0,
i - 0,
j - 0,
k - 1,
l - 0,
m - 1,
n - 1,
o - 5,
p - 0,
q - 0,
r - 0,
s - 2,
t - 4,
u - 0,
v - 0,
w - 2,
x - 0,
y - 1,
z - 0,
perl -Mfeature=say -e '$a=join("",<>);say join(",\n", map { sprintf("%s - %d", $_, ($d=()=$a=~/$_/gi)); } ("a".."z"))'
Berikut ini solusi menggunakan Python:
#!/usr/bin/env python2
import collections, string
with open('1.txt') as f:
input_string = f.read().replace('\n', '').lower()
count_dict = collections.Counter(input_string)
for char in string.lowercase:
print char + ' - ' + str(count_dict[char]) + ','
Di sini kita telah menggunakan kelas collectionsmodul Counteruntuk menghitung jumlah kemunculan setiap karakter, kemudian untuk tujuan pencetakan kita telah menggunakan stringmodul untuk mendapatkan semua huruf kecil dengan variabel string.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 menjalankan python count.pyuntuk menjalankan file, dari direktori lain menggunakan jalur absolut ke file untuk menjalankannya yaitu python /absolute/path/to/count.py.
Beberapa waktu yang lalu saya menulis program C untuk melakukan itu, karena saya membutuhkannya untuk melihat file besar dan menghasilkan beberapa statika.
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include <sysexits.h>
inline static double square(double x)
{
return x * x;
}
int main()
{
static const unsigned distribution_size = 1 << CHAR_BIT;
int rv = EX_OK;
uintmax_t *distribution = calloc(distribution_size, sizeof(*distribution));
{
int c;
while ((c = getchar()) != EOF)
distribution[c]++;
if (ferror(stdin)) {
perror("I/O error on standard input");
rv = EX_IOERR;
}
}
uintmax_t sum = 0;
for (unsigned i = 0; i != distribution_size; i++)
sum += distribution[i];
double avg = (double) sum / distribution_size;
double var_accum = 0.0;
for (unsigned i = 0; i != distribution_size; i++)
{
const uintmax_t x = distribution[i];
printf("'%c' (%02X): %20ju", isprint((int) i) ? i : ' ', i, x);
if (x != 0) {
var_accum += square((double) x - avg);
printf(" (%+.2e %%)\n", ((double) x / avg - 1.0) * 100.0);
} else {
var_accum += square(avg);
putchar('\n');
}
}
double stdev = sqrt(var_accum / distribution_size);
double varcoeff = stdev / avg;
printf(
"total: %ju\n"
"average: %e\n"
"standard deviation: %e\n"
"variation coefficient: %e\n",
sum, avg, stdev, varcoeff);
free(distribution);
return rv;
}
kompilasi dengan (dengan asumsi kode sumber berada di character-distribution.c):
cc -std=c99 -O2 -g0 -o character-distribution character-distribution.c
jalankan dengan:
./character-distribution < 1.txt
Jika Anda tidak memiliki kompiler C yang siap, instal GCC:
sudo apt-get install gcc build-essential
Solusi serupa dengan @heemayl, dengan kode yang lebih ketat, yang berfungsi pada Python 2.7 dan Python 3.
#!/usr/bin/python
import collections
import fileinput
import itertools
import string
count = collections.Counter(itertools.chain(*fileinput.input()))
print(',\n'.join('{} - {}'.format(c, count[c] + count[c.upper()])
for c in string.ascii_lowercase))
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 dalam countvariabel.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.GNU awk 4.1
awk -iwalkarray '{for (;NF;NF--) b[$NF]++} END {walk_array(b)}' FS=
[A] = 1
[O] = 1
[w] = 2
[k] = 1
[y] = 1
[T] = 1
[n] = 1
[a] = 4
[o] = 4
[c] = 1
[s] = 2
[t] = 3
[M] = 1
Jika Anda memiliki versi GNU awk yang lebih lama, Anda dapat menggunakannya for (c in b) print c, b[c].
Inilah jawabannya menggunakan ruby. Hal ini dilakukan dengan mengubah string menjadi daftar unik karakter yang berbeda dan menggunakan metode hitungan pada masing-masing karakter.
#!/usr/bin/env ruby
String content = IO.read("1.txt")
content.split("").uniq.sort.each { |chr| puts( chr + ' - ' + content.count(chr).to_s) }