統計文件中出現的單詞次數

 

這裏以kevin.txt文件內容(單詞由一個或多個空格字符分隔)爲例進行簡單說明前端

[root@centos6-test06 ~]# cat /root/kevin.txt 
the world kevin is the
is world grace the kevin
art the kevin the is kevin

統計kevin.txt文件中出現的單詞次數shell

第一種方法:結合grep和awk編寫shell腳本express

腳本內容以下:
[root@centos6-test06 ~]# cat count.sh
#! /bin/bash
# solution 1
if [ $# -eq 0 ]
then
echo "Usage:$0 args error"
exit 0
fi
if [ $# -ge 2 ]
then
echo "analyse the first file $1"
fi

#get the first file
filename=$1
grep -E -o "\b[[:alpha:]]+\b" $filename | awk ' { count[$0]++ } 
END{printf("%-20s%s\n","Word","Count");
for(word in count)
{printf("%-20s%s\n",word,count[word])}
}'

=======================================================================
腳本參數說明:
-eq:   等於
-ne:   不等於
-le:   小於等於
-ge:   大於等於
-lt:   小於
-gt:  大於
\b     backspace,printf參數

awk說明
awk由內容和動做組成;awk pattern {action}
pattern能夠是BEGIN、END、expression
能夠執行 for ( var in array ) statement

1)BEGIN模塊:這個模塊包括了一個操做塊(也就是"{ }"內的內容)。該操做塊是在文件輸入以前執行的,也就是不須要輸入任何文件數據,也能執行該模塊。
BEGIN模塊經常使用於設置修改內置變量如(OFS,RS,FS等),爲用戶自定義的變量賦初始值或者打印標題信息等。
BEGIN模塊中的語句操做以":"標誌或者分行隔開。
好比:
[root@centos6-test06 ~]# awk 'BEGIN{print "Hello World! Begin doing!"}'
Hello World! Begin doing!

2)END模塊:與BEGIN模塊相反,是處理完文件後的操做。不匹配任何輸入行,經常使用於輸出一些總結信息。

3)匹配表達式:
[[:alpha:]]  表明字母
[[:alnum:]]  表明字母與數字字符
[a-zA-Z0-9]  表明單個字母和數字字符

匹配到/root/kevin.txt中全部的單詞
[root@centos6-test06 ~]# grep -E "\b[[:alpha:]]+\b" /root/kevin.txt

把匹配到的單詞每行1個打印出來
[root@centos6-test06 ~]# grep -E -o "\b[[:alpha:]]+\b" /root/kevin.txt

能匹配到整個單詞
"\b[[:alpha:]]+\b"
=======================================================================

開始統計:
[root@centos6-test06 ~]# /bin/bash count.sh /root/kevin.txt 
Word                Count
world               2
art                 1
the                 5
grace               1
is                  3
kevin               4

第二種方法:使用grep匹配表達式centos

[root@centos6-test06 ~]# grep -E -o "\b[[:alpha:]]+\b" /root/kevin.txt|sort|uniq -c|sort -rn
      5 the
      4 kevin
      3 is
      2 world
      1 grace
      1 art

第三種方法:使用awk匹配表達式bash

[root@centos6-test06 ~]# awk -F' ' '{for(i=1;i<=NF;i=i+1){print $i}}' /root/kevin.txt |sort|uniq -c|sort -nr|awk -F' ' '{printf("%s %s\n",$2,$1)}'
the 5
kevin 4
is 3
world 2
grace 1
art 1

一般,awk逐行處理文本。awk每接收文件的一行,而後執行相應的命令來處理。
找到指定單詞,自定義變量count自增,最後輸出語句和count值
sort: 把各行按首字母排列順序從新排列起來
sort -nr: 每行都以數字開頭,按數字從達到小,排列各行
uniq -c: 統計各行出現的次數,並把次數打印在每行前端
NF: 瀏覽記錄的域的個數

例如;
搜索統計單詞"kevin"的個數
[root@centos6-test06 ~]# awk -F : '/kevin/{count++} END{print "the count is ",count}' /root/kevin.txt 
the count is  3

第四種方式:統計kevin.txt文件中的單詞個數,並指定排名個數(利用管道組成的一條命令工具

寫一個shell腳本,查找kevin.txt文本中n個出現頻率最高的單詞,輸出結果須要顯示單詞出現的次數,並按照次數從大到小排序。分爲如下幾步:
1)將文本文件以一行一個單詞的形式顯示出來;
2)將單詞中的大寫字母轉化成小寫字母,即Word和word認爲一個單詞;
3)對單詞進行排序;
4)對排序好的單詞列表統計每一個單詞出現的次數;
5)最後顯示單詞列表的前n項。

[root@centos6-test06 ~]# cat tr.sh
  
#!/bin/bash  
#查找文本中n個出現頻率最高的單詞

count=$1                                #$1是輸出頻率最高單詞的個數  
  
cat $2 |                                #$2是目標文本文件名稱也但是是字符串  
tr -cs "[a-z][A-Z][0-9]" "\n" |         #tr是sed的簡化,-c用前字符串中字符集的補集替換成後字符串即將不是字符和數字的單詞替換換行  
                                        #-s刪除全部重複出現換行,只保留第一個  
                                        #能夠寫成tr -cs "[a-z][A-Z][0-9]" "\012"或tr -cs "[a-z][A-Z][0-9]" "[\012*]"  
  tr A-Z a-z |                          #將大寫字母換化爲小寫字母  
    sort |                              #對單詞進行排序  
      uniq -c |                         #刪除文本文件中重複出現的行,-c在每列旁邊顯示該行重複出現的次數  
        sort -k1nr -k2 |                #字符串以空格分紅域,先按第一個域排序,在按第二個域排序  
                                        #-k1指定第一個域,-n按數字大寫排序,-r排序結果逆向顯示  
          head -n $count                #顯示前n行  


取kevin.txt文件中出現頻率最高的1個單詞
[root@centos6-test06 ~]# sh tr.sh 1 /root/kevin.txt 
      5 the

取kevin.txt文件中出現頻率最高的2個單詞
[root@centos6-test06 ~]# sh tr.sh 2 /root/kevin.txt 
      5 the
      4 kevin

取kevin.txt文件中出現頻率最高的3個單詞
[root@centos6-test06 ~]# sh tr.sh 3 /root/kevin.txt 
      5 the
      4 kevin
      3 is

爲便於理解可在shell命令行下將管道分解,能夠舉以下一例,將輸出的內容中的單詞單個一行打印出來
[root@centos6-test06 ~]# echo "kevin is a good boy come on baby" | tr -cs "[a-z][A-Z][0-9]" "\n"
kevin
is
a
good
boy
come
on
baby

總結
1)sort -k2第二個域會按字母順序對單詞進行排序,字母以a開頭的單詞在以z開頭的單詞後面。
2)上述一條簡單的命令綜合應用了tr、sort、uniq、head等文本處理命令,顯示shell工具在文本處理方面的強大。
相關文章
相關標籤/搜索