這裏以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工具在文本處理方面的強大。