Как подсчитать уникальные термины в текстовом файле без учета регистра? - PullRequest
2 голосов
/ 27 мая 2009

Это может быть любой язык высокого уровня, который, вероятно, будет доступен в типичной Unix-подобной системе (Python, Perl, awk, стандартные утилиты unix {sort, uniq} и т. Д.) Надеюсь, это достаточно быстро, чтобы сообщить общее количество уникальных терминов для текстового файла размером 2 МБ.

Мне это нужно только для быстрой проверки работоспособности, поэтому его не нужно тщательно проектировать.

Помните, без учета регистра.

Большое спасибо, ребята.

Примечание: если вы используете Python, не используйте код версии 3. Система, на которой я работаю, имеет только 2.4.4.

Ответы [ 8 ]

6 голосов
/ 27 мая 2009

В Perl:

my %words; 
while (<>) { 
    map { $words{lc $_} = 1 } split /\s/); 
} 
print scalar keys %words, "\n";
5 голосов
/ 27 мая 2009

Использование команд bash / UNIX:

sed -e 's/[[:space:]]\+/\n/g' $FILE | sort -fu | wc -l
4 голосов
/ 27 мая 2009

Вот Perl с одним вкладышем:

perl -lne '$h{lc $_}++ for split /[\s.,]+/; END{print scalar keys %h}' file.txt

Или перечислить количество для каждого элемента:

perl -lne '$h{lc $_}++ for split /[\s.,]+/; END{printf "%-12s %d\n", $_, $h{$_} for sort keys %h}' file.txt

Это делает попытку обработать пунктуацию так, чтобы "foo". считается "foo", тогда как "not" рассматривается как одно слово, но вы можете настроить регулярное выражение в соответствии со своими потребностями.

4 голосов
/ 27 мая 2009

Использование только стандартных утилит Unix:

< somefile tr 'A-Z[:blank:][:punct:]' 'a-z\n' | sort | uniq -c

Если вы работаете в системе без Gnu tr, вам нужно заменить "[:blank:][:punct:]" списком всех пробелов и знаков пунктуации, которые вы хотели бы считать разделителями слов, скорее чем часть слова, например, "\t.,;".

Если вы хотите, чтобы выходные данные были отсортированы в порядке убывания частоты, вы можете добавить «| sort -r -n» к концу этого.

Обратите внимание, что это также приведет к неуместному количеству пробелов; если вас это беспокоит, после tr вы можете использовать sed для фильтрации пустых строк.

4 голосов
/ 27 мая 2009

В Python 2.4 (возможно, он работает и в более ранних системах):

#! /usr/bin/python2.4
import sys
h = set()
for line in sys.stdin.xreadlines():
  for term in line.split():
    h.add(term)
print len(h)

В Perl:

$ perl -ne 'for (split(" ", $_)) { $H{$_} = 1 } END { print scalar(keys%H), "\n" }' <file.txt
3 голосов
/ 30 мая 2009

Более короткая версия на Python:

print len(set(w.lower() for w in open('filename.dat').read().split()))

Считывает весь файл в память, разбивает его на слова, используя пробелы, преобразует каждое слово в нижний регистр, создает (уникальный) набор из слов в нижнем регистре, считает их и печатает выходные данные.

Также возможно использование одного вкладыша:

python -c "print len(set(w.lower() for w in open('filename.dat').read().split()))"
3 голосов
/ 27 мая 2009

Просто (52 удара):

perl -nE'@w{map lc,split/\W+/}=();END{say 0+keys%w}'

Для более старых версий Perl (55 ударов):

perl -lne'@w{map lc,split/\W+/}=();END{print 0+keys%w}'
0 голосов
/ 27 мая 2009

Вот awk oneliner.

$ gawk -v RS='[[:space:]]' 'NF&&!a[toupper($0)]++{i++}END{print i}' somefile
  • «NF» означает «если есть характер».
  • '! A [topuuer [$ 0] ++]' означает 'показывать только уникальные слова ".
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...