파일의 다양한 문자 수를 계산하는 방법은 무엇입니까?

파일의 다양한 문자 수를 계산하는 방법은 무엇입니까?

파일의 고유 문자 수를 출력하는 프로그램이 필요합니다. 예:

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

이를 수행하는 도구가 있습니까?

답변1

다음이 작동합니다.

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

먼저 각 문자 뒤에 개행 문자를 삽입하여 각 문자를 자체 줄에 배치합니다. 그런 다음 정렬해 보겠습니다. 그런 다음 uniq 명령을 사용하여 중복을 제거하고 각 줄 앞에 해당 문자의 발생 횟수를 추가합니다.

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

답변2

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) }'

답변3

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

답변4

간단하고 비교적 성능이 좋습니다.

fold -c1 testfile.txt | sort | uniq -c

fold매 1 문자마다 줄 바꿈(예: 개행 삽입)하도록 지시하세요 .



테스트 방법:

  • 128MB 전체 ASCII 파일
    • find . -type f -name '*.[hc]' -exec cat {} >> /tmp/big.txt \;일부 코드 기반으로 생성되었습니다.
  • 워크스테이션급 머신(가상 머신이 아닌 실제 철)
  • 환경 변수LC_ALL=C

내림차순으로 실행 시간:

  • 스티븐의 sed|sort|uniq솔루션(https://unix.stackexchange.com/a/5011/427210): 102.5초
  • fold|sort|uniq솔루션: 59.3초
  • 옵션이 포함된 내 fold|sort|uniq솔루션 : 38.9초--buffer-size=12Gsort
  • fold|sort|uniq솔루션, 주어진 옵션 --buffer-size=12G: 37.9 초--stablesort
  • Giles의 perl솔루션(https://unix.stackexchange.com/a/5013/427210): 34.0초
    • 우승자! 그들이 말했듯이 가장 빠른 정렬은정렬할 필요가 없습니다.. :-)

관련 정보