Yanıtlar:
Bunu kullanabilirsiniz:
sed 's/./&\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
sedKısmında, her karakterin ardından bir yeni satır yerleştirir. Sonra biz sortalfabetik olarak çıkıyoruz . Ve sonunda uniqmeydana gelen olayları sayar. Büyük -i/ uniqküçük harf duyarsızlığı istemiyorsanız bayrağı kaldırılabilir.
sort -k 2alfanümerik olarak listelemek için çıktıyı tekrar boruya bağlamak olacaktır .
sed -e $'s/\(.\)/\\1\\\n/g'(ayrıca bkz. Stackoverflow.com/a/18410122/179014 )
| sort -rnk 1. Ve benim gibi çok büyük dosyalarla uğraşıyorsanız, gerçek sayılar için bir proxy almak için sadece birkaç bin satır cat 1.txt | shuf -n 10000 | sed 's/\(.\)/\1\n/g' | sort | uniq -ic | sort -rnk 1
Biraz geç, ancak seti tamamlamak için başka bir python (3) yaklaşımı, sonucu sıraladı:
#!/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
Dosyayı okuyun, boşlukları atlayın ve "karakter" olarak döndürür:
chars = open(sys.argv[1]).read().strip().replace("\n", "")Bir (sıralı) benzersiz set oluşturun:
sorted(set([c for c in chars]))Karakterlerin her birinin oluşumunu sayın ve yazdırın:
print(c+" -", chars.count(c)) for c in <uniques>chars_count.pyDosyayla bağımsız değişken olarak aşağıdakilerden birini kullanarak çalıştırın:
/path/to/chars_count.py </path/to/file>
komut dosyası yürütülebilirse veya:
python3 /path/to/chars_count.py </path/to/file>
değilse
Varsayılan olarak awk F IELD S eparator (FS) 'dir uzay veya sekme . Her karakteri saymak istiyor bu yana, hiçbir şey (FS yeniden tanımlamak zorunda kalacak FS="") bir diziye ve iç sonunda her ayrı satırda karakteri ve ona tasarrufu bölmek END{..}takip ederek toplam oluşumlarını yazdırmak bloğun awk komutu:
$ 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
Gelen {for (i=1;i<=NF;i++) a[$i]++} ... FS="" ...blokta sadece karakterleri böler. Ve
de END{for (c in a) print c,a[c]}bloğa biz diziye döngü vardır ave içinde karakterini kurtardı yazdırma'den print cve olaylar onun sayıa[c]
forSaymak istediğiniz tüm karakterler için bir döngü yapın grep -iove karakterin ve görmezlik durumunun tüm oluşumlarını elde etmek, wc -lörnekleri saymak ve sonucu yazdırmak için kullanın.
Bunun gibi:
#!/bin/bash
filename="1.txt"
for char in {a..z}
do
echo "${char} - `grep -io "${char}" ${filename} | wc -l`,"
done
Komut dosyası bunu verir:
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,
Yorumdan sonra DÜZENLE
Yazdırılabilir tüm karakterler için bir döngü oluşturmak için bunu yapabilirsiniz:
#!/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
Bu 32 ila 126 arasındaki tüm ANSI karakterlerini sayar - bunlar en yaygın olarak okunabilir karakterlerdir. Bunun yoksayma durumunu kullanmadığını unutmayın.
bundan çıktı:
- 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,
i. (sorunuzda beklenen sonuçta yalnızca 3 tane vardı)
grepdefalarca tüm girişi.
İşte başka bir çözüm (awk olarak) ...
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 '...': doğrudan söyleyebilirsin awk '...' file.
Aşağıdaki perloneliner sayımı yapar. Normal ifadeleri (eşleşme sayısını elde etmek için) liste bağlamına koydum ve skaler bağlama koydum:
$ 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"))'
İşte Python kullanan bir çözüm:
#!/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]) + ','
Burada , her karakterin tekrarlama sayısını saymak için collectionsmodül Countersınıfını kullandık, daha sonra yazdırma amacıyla, stringtüm küçük harfleri değişken tarafından almak için modülü kullandık string.lowercase.
Yukarıdaki komut dosyasını istediğiniz herhangi bir ad vererek bir dosyaya kaydedin, örn count.py. Şimdi dosyanın kaydedildiği python count.pydizinden dosyayı yürütmek için çalıştırabilirsiniz, diğer herhangi bir dizinden dosyayı yürütmek için mutlak yolu kullanın yani python /absolute/path/to/count.py.
Bir süre önce bunu yapmak için bir C programı yazdım, çünkü büyük dosyalara bakmak ve bazı statikler üretmek için programa ihtiyacım vardı .
#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;
}
ile derleyin (kaynak kodun içinde olduğu varsayılarak character-distribution.c):
cc -std=c99 -O2 -g0 -o character-distribution character-distribution.c
şununla koş:
./character-distribution < 1.txt
Hazır bir C derleyiciniz yoksa GCC'yi yükleyin:
sudo apt-get install gcc build-essential
@Heemayl'e benzer bir çözüm, Python 2.7 ve Python 3 üzerinde çalışan daha sıkı kod ile.
#!/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))
İlk açıklama, count = collections.Counter(…)tüm gerçek işi yapar.
fileinput.input() stdin aracılığıyla veya komut satırı argümanları olarak girilebilen girdinin her satırını okur.* her seferinde bir satır yerine bir karaktere bakmasını sağlar.count = Counter(…)her karakterin oluşumunu tek bir geçişte verimli bir şekilde sayar ve sonucu countdeğişkene kaydeder.İkinci satır sadece sonuçları yazdırır.
'{} - {}'.format(c, count[c] + count[c.upper()]) for c in string.ascii_lowercase her karakterin ve sayılarının bir listesini yapar.print(',\n'.join(…)) istenen biçime koyar: her satıra bir tane, virgülle ayrılmış ancak son satırda virgül yoktur.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
GNU awk'nin önceki bir sürümüne sahipseniz kullanabilirsiniz for (c in b) print c, b[c].