답변:
이것을 사용할 수 있습니다 :
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
이 sed부분은 모든 문자 뒤에 줄 바꿈을 배치합니다. 그 다음 sort순으로 OUPUT. 그리고 마지막 uniq으로 발생 횟수를 계산합니다. 대소 문자를 구분하지 않으려면 의 -i플래그를 uniq생략 할 수 있습니다.
sort -k 2알파벳 순으로 나열하는 것입니다.
sed -e $'s/\(.\)/\\1\\\n/g'에서는 stackoverflow.com/a/18410122/179014 참조 )
| sort -rnk 1. 그리고 만약 당신이 매우 큰 파일을 다루는 경우, 당신은 실제 수에 대한 프록시를 얻기 위해 수천 줄을 샘플링 할 수 있습니다.cat 1.txt | shuf -n 10000 | sed 's/\(.\)/\1\n/g' | sort | uniq -ic | sort -rnk 1
조금 늦었지만 세트를 완성하기 위해 또 다른 python (3) 접근 방식은 다음과 같이 정렬되었습니다.
#!/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
파일을 읽고 공백을 건너 뛰고 "문자"로 반환합니다.
chars = open(sys.argv[1]).read().strip().replace("\n", "")고유 한 (정렬 된) 고유 세트를 작성하십시오.
sorted(set([c for c in chars]))각 문자의 발생 횟수를 세고 인쇄하십시오.
print(c+" -", chars.count(c)) for c in <uniques>chars_count.py다음 중 하나를 수행하여 파일을 인수로 실행하십시오.
/path/to/chars_count.py </path/to/file>
스크립트가 실행 가능한 경우 또는
python3 /path/to/chars_count.py </path/to/file>
그렇지 않다면
기본적으로 AWK F는 의 ield S의 eparator (FS) 인 공간 또는 탭 . 각 문자를 세고 싶기 때문에 FS를 none ( FS="") 으로 다시 정의하여 각 문자를 별도의 줄로 나누고 배열에 저장하고 END{..}블록 내부의 끝 에서 다음 awk 명령으로 총 발생 횟수를 인쇄해야합니다 .
$ 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
에서 {for (i=1;i<=NF;i++) a[$i]++} ... FS="" ...블록 우리는 단지 문자를 분할합니다. 그리고
에 END{for (c in a) print c,a[c]}블록 우리는 배열에 반복되어 a그 안에 문자를 저장 인쇄가 print c와 발생의 수a[c]
for계산하려는 모든 문자에 대해 루프를 수행 grep -io하고 문자 및 대소 문자를 무시하고 wc -l인스턴스를 계산하고 결과를 인쇄하는 데 사용하십시오.
이처럼 :
#!/bin/bash
filename="1.txt"
for char in {a..z}
do
echo "${char} - `grep -io "${char}" ${filename} | wc -l`,"
done
스크립트는 이것을 출력합니다 :
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,
댓글 후 수정
인쇄 가능한 모든 문자에 대해 루프를 만들려면 다음을 수행하십시오.
#!/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
32에서 126까지의 모든 ANSI 문자를 계산합니다. 가장 일반적으로 읽을 수있는 문자입니다. 이것은 대소 문자를 무시하지 않습니다.
이것의 결과는 다음과 같습니다.
- 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,
igrep에서 를 제거하십시오 . (질문에서 당신은 예상 결과에서 3을 얻었습니다)
grep.
여기 또 다른 해결책 (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 '...': 직접 말할 수 있습니다 awk '...' file.
다음 perloneliner가 계산을 수행합니다. 정규식을 목록 컨텍스트에 넣고 (일치 수를 얻기 위해) 스칼라 컨텍스트에 넣습니다.
$ 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"))'
다음은 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]) + ','
여기서 우리는 collections모듈의 Counter클래스를 사용하여 각 문자의 발생 횟수를 계산 한 다음 인쇄 목적으로 string모듈을 사용 하여 변수로 모든 소문자를 가져 왔습니다 string.lowercase.
예를 들어 위의 스크립트를 원하는 이름으로 파일에 저장하십시오 count.py. 이제 파일이 저장된 동일한 디렉토리에서 파일을 실행 python count.py하기 위해 간단히 실행할 수 있으며 , 다른 디렉토리에서 파일의 절대 경로를 사용하여 파일을 실행할 수 python /absolute/path/to/count.py있습니다.
얼마 전에 저는 큰 파일 을보고 약간의 스태틱을 생성 해야했기 때문에 C 프로그램을 작성했습니다 .
#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;
}
로 컴파일 (소스 코드가 있다고 가정 character-distribution.c) :
cc -std=c99 -O2 -g0 -o character-distribution character-distribution.c
로 실행 :
./character-distribution < 1.txt
C 컴파일러가 준비되어 있지 않으면 GCC를 설치하십시오.
sudo apt-get install gcc build-essential
Python 2.7 및 Python 3에서 작동하는 더 엄격한 코드를 사용하여 @heemayl과 비슷한 솔루션입니다.
#!/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))
첫 번째 진술 count = collections.Counter(…)은 모든 실제 작업을 수행합니다.
fileinput.input() stdin을 통해 또는 명령 행 인수로 파이프 될 수있는 입력의 모든 행을 읽습니다.* 한 번에 한 줄이 아닌 한 번에 한 문자를 고려합니다.count = Counter(…)단일 패스에서 각 문자의 발생을 효율적으로 계산하고 결과를 count변수 에 저장합니다 .두 번째 줄은 결과를 인쇄합니다.
'{} - {}'.format(c, count[c] + count[c.upper()]) for c in string.ascii_lowercase 각 캐릭터와 그 수의 목록을 만듭니다.print(',\n'.join(…)) 원하는 형식으로 입력합니다 : 한 줄에 하나씩, 쉼표로 구분되지만 마지막 줄에는 쉼표가 없습니다.