Как создать список частот каждого слова в файле?
У меня есть файл вроде этого:
This is a file with many words.
Some of the words appear more than once.
Some of the words only appear one time.
Я хотел бы создать список из двух столбцов. Первый столбец показывает, какие слова появляются, второй столбец показывает, как часто они появляются, например:
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
words3
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
- Чтобы сделать эту работу проще, перед обработкой списка я удалю все знаки препинания и изменю весь текст на строчные буквы.
- Если вокруг него нет простого решения,
words
и word
могут считаться двумя отдельными словами.
Пока у меня есть это:
sed -i "s/ /\n/g" ./file1.txt # put all words on a new line
while read line
do
count="$(grep -c $line file1.txt)"
echo $line"@"$count >> file2.txt # add word and frequency to file
done < ./file1.txt
sort -u -d # remove duplicate lines
По какой-то причине это только показывает "0" после каждого слова.
Как я могу сгенерировать список каждого слова, которое появляется в файле, вместе с информацией о частоте?
Ответы
Ответ 1
Не sed
и grep
, но tr
, sort
, uniq
и awk
:
% (tr ' ' '\n' | sort | uniq -c | awk '{print $2"@"$1}') <<EOF
This is a file with many words.
Some of the words appear more than once.
Some of the words only appear one time.
EOF
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
Ответ 2
uniq -c уже делает то, что вы хотите, просто выполните сортировку ввода:
echo 'a s d s d a s d s a a d d s a s d d s a' | tr ' ' '\n' | sort | uniq -c
выход:
6 a
7 d
7 s
Ответ 3
Содержимое входного файла
$ cat inputFile.txt
This is a file with many words.
Some of the words appear more than once.
Some of the words only appear one time.
Используя sed | sort | uniq
$ sed 's/\.//g;s/\(.*\)/\L\1/;s/\ /\n/g' inputFile.txt | sort | uniq -c
1 a
2 appear
1 file
1 is
1 many
1 more
2 of
1 once
1 one
1 only
2 some
1 than
2 the
1 this
1 time
1 with
3 words
uniq -ic
будет считать и игнорировать регистр, но в списке результатов будет This
вместо This
.
Ответ 4
Это может сработать для вас:
tr '[:upper:]' '[:lower:]' <file |
tr -d '[:punct:]' |
tr -s ' ' '\n' |
sort |
uniq -c |
sed 's/ *\([0-9]*\) \(.*\)/\[email protected]\1/'
Ответ 5
Пусть используется AWK!
Эта функция отображает частоту каждого слова, входящего в предоставленный файл, в порядке убывания:
function wordfrequency() {
awk '
BEGIN { FS="[^a-zA-Z]+" } {
for (i=1; i<=NF; i++) {
word = tolower($i)
words[word]++
}
}
END {
for (w in words)
printf("%3d %s\n", words[w], w)
} ' | sort -rn
}
Вы можете вызвать его в своем файле следующим образом:
$ cat your_file.txt | wordfrequency
Источник: AWK-ward Ruby
Ответ 6
Для сортировки требуется GNU AWK (gawk
). Если у вас есть еще один AWK без asort()
, это можно легко отрегулировать, а затем передать на sort
.
awk '{gsub(/\./, ""); for (i = 1; i <= NF; i++) {w = tolower($i); count[w]++; words[w] = w}} END {qty = asort(words); for (w = 1; w <= qty; w++) print words[w] "@" count[words[w]]}' inputfile
Разбито на несколько строк:
awk '{
gsub(/\./, "");
for (i = 1; i <= NF; i++) {
w = tolower($i);
count[w]++;
words[w] = w
}
}
END {
qty = asort(words);
for (w = 1; w <= qty; w++)
print words[w] "@" count[words[w]]
}' inputfile
Ответ 7
Сделайте это в Python 3!
"""Counts the frequency of each word in the given text; words are defined as
entities separated by whitespaces; punctuations and other symbols are ignored;
case-insensitive; input can be passed through stdin or through a file specified
as an argument; prints highest frequency words first"""
# Case-insensitive
# Ignore punctuations `[email protected]#$%^&*()_-+={}[]\|:;"'<>,.?/
import sys
# Find if input is being given through stdin or from a file
lines = None
if len(sys.argv) == 1:
lines = sys.stdin
else:
lines = open(sys.argv[1])
D = {}
for line in lines:
for word in line.split():
word = ''.join(list(filter(
lambda ch: ch not in "`[email protected]#$%^&*()_-+={}[]\\|:;\"'<>,.?/",
word)))
word = word.lower()
if word in D:
D[word] += 1
else:
D[word] = 1
for word in sorted(D, key=D.get, reverse=True):
print(word + ' ' + str(D[word]))
Назовите этот script "frequency.py" и добавьте строку в "~/.bash_aliases":
alias freq="python3 /path/to/frequency.py"
Теперь, чтобы найти частотные слова в вашем файле "content.txt", выполните следующие действия:
freq content.txt
Вы также можете выводить на него вывод:
cat content.txt | freq
И даже анализировать текст из нескольких файлов:
cat content.txt story.txt article.txt | freq
Если вы используете Python 2, просто замените
-
''.join(list(filter(args...)))
с filter(args...)
-
python3
с python
-
print(whatever)
с print whatever
Ответ 8
Вы можете использовать хеш-таблицу для создания гистограммы или, возможно, использовать Trie.