我想在文字檔中尋找 10 個最常見的單字。首先,解決方案應該針對擊鍵進行最佳化(換句話說 - 我的時間)。其次,為了表演。以下是我迄今為止獲得前 10 名的內容:
cat test.txt | tr -c '[:alnum:]' '[\n*]' | uniq -c | sort -nr | head -10
6 k
2 g
2 e
2 a
1 r
1 k22
1 k
1 f
1 eeeeeeeeeeeeeeeeeeeee
1 d
我可以製作一個 java、python 等程序,將(單字、numberOfOccurences)儲存在字典中並對值進行排序,或者我可以使用 MapReduce,但我會針對擊鍵進行最佳化。
是否有誤報?有沒有更好的辦法?
答案1
這幾乎是尋找“N 個最常見的事物”的最常見方法,除了您缺少 a sort
,並且您有一個免費的cat
:
tr -c '[:alnum:]' '[\n*]' < test.txt | sort | uniq -ci | sort -nr | head -10
sort
如果你不在 the之前加上 a ,uniq -ci
你可能會得到很多錯誤的單例單字。 uniq
只有獨特的線條,而不是整體的獨特性。
您可能想使用一個技巧,「停止詞」。如果您正在查看英語文本(對不起,這裡是單語北美語),像“of”、“and”、“the”這樣的單字幾乎總是佔據前兩到三個位置。您可能想消除它們。 GNU Groff 發行版有一個名為eign
其中的文件,其中包含相當不錯的停用詞列表。我的 Arch 發行版有/usr/share/groff/current/eign
,但我想我也見過/usr/share/dict/eign
或/usr/dict/eign
在舊的 Unix 中。
您可以像這樣使用停用詞:
tr -c '[:alnum:]' '[\n*]' < test.txt |
fgrep -v -w -f -i /usr/share/groff/current/eign |
sort | uniq -ci | sort -nr | head -10
我的猜測是,大多數人類語言需要從有意義的詞頻計數中刪除類似的“停用詞”,但我不知道在哪裡建議獲取其他語言的停用詞列表。
-w
on 標誌啟用fgrep
全字匹配。這可以避免僅包含短暫停止詞的單字(例如“a”或“i”)出現誤報。該-i
標誌打開uniq
並fgrep
在比較單字時忽略大小寫。
答案2
這對於 utf-8 效果更好:
$ sed -e 's/\s/\n/g' < test.txt | sort | uniq -c | sort -nr | head -10
答案3
讓我們使用 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
對於前 10 個單字:
$ cat your_file.txt | wordfrequency | head -10
來源:AWK 病態 Ruby
答案4
讓我們使用哈斯克爾吧!
這正在變成一場語言戰爭,不是嗎?
import Data.List
import Data.Ord
main = interact $ (=<<) (\x -> show (length x) ++ " - " ++ head x ++ "\n")
. sortBy (flip $ comparing length)
. group . sort
. words
用法:
cat input | wordfreq
或者:
cat input | wordfreq | head -10