it-swarm-ko.tech

파일의 다른 문자 수를 어떻게 계산할 수 있습니까?

파일에있는 다른 문자 수를 출력하는 프로그램이 필요합니다. 예:

> stats testfile
' ': 207
'e': 186
'n': 102

이 작업을 수행하는 도구가 있습니까?

19
Mnementh

다음이 작동합니다.

$ sed 's/\(.\)/\1\n/g' text.txt | sort | uniq -c

먼저 모든 문자 뒤에 개행 문자를 삽입하여 각 문자를 자체 행에 넣습니다. 그런 다음 정렬합니다. 그런 다음 uniq 명령을 사용하여 중복을 제거하고 각 줄에 해당 문자의 발생 수를 접두사로 붙입니다.

목록을 빈도별로 정렬하려면 모두 sort -nr.

20
Steven D

Steven의 솔루션은 훌륭하고 간단한 솔루션입니다. 정렬 단계 때문에 매우 큰 파일 (RAM의 절반에 편안하게 맞지 않는 파일)의 경우 성능이 좋지 않습니다. 다음은 awk 버전입니다. 또한 몇 가지 특수 문자 (줄 바꿈, ', \, :)에 대해 올바른 작업을 수행하기 때문에 조금 더 복잡합니다.

awk '
  {for (i=1; i<=length; i++) ++c[substr($0,i,1)]; ++c[RS]}
  function chr (x) {return x=="\n" ? "\\n" : x==":" ? "\\072" :
                           x=="\\" || x=="'\''" ? "\\" x : x}
  END {for (x in c) printf "'\''%s'\'': %d\n", chr(x), c[x]}
' | sort -t : -k 2 -r | sed 's/\\072/:/'

동일한 원리에 대한 Perl 솔루션이 있습니다. Perl은 내부적으로 정렬 할 수 있다는 장점이 있습니다. 또한 파일이 개행 문자로 끝나지 않으면 추가 개행을 올바르게 계산하지 않습니다.

Perl -ne '
  ++$c{$_} foreach split //;
  END { printf "'\''%s'\'': %d\n", /[\\'\'']/ ? "\\$_" : /./ ? $_ : "\\n", $c{$_}
        foreach (sort {$c{$b} <=> $c{$a}} keys %c) }'

느리지 만 비교적 메모리 친화적 인 버전으로 Ruby를 사용합니다. 입력 크기에 관계없이 약 12MB의 RAM.

# count.rb
ARGF.
  each_char.
  each_with_object({}) {|e,a| a[e] ||= 0; a[e] += 1}.
  each {|i| puts i.join("\t")}

Ruby count.rb < input.txt
t       20721
d       20628
S       20844
k       20930
h       20783
... etc
1
Jared Beck