1. 程式人生 > >文本操作4(tr,sort,unip)

文本操作4(tr,sort,unip)

tr sort uniq

需求
  • 統計一個文本文件中各個單詞出現的個數

    解決方案

  • 我們知道wc命令可以統計文本的行數,字數和字符數,但是它不能統計每一個單詞出現的個數,因此我們需要自己構建一個腳本來實現這個功能。要想實現這個腳本,需要用到三個命令:tr,sort,uniq。
  • 具體代碼如下【count_words.sh】
    
    [root@akuilinux01 shellXT]# vim count_words.sh
    #!/bin/bash

#定義函數count,用來統計一個文件中的字數
count(){
#函數需要一個參數才可以被正確調用
if [ $# != 1 ]
then
echo "Need one file parameter to work!"

exit 1 ;
fi

    #刪除標點符號和特殊字符
    #構建一個很長的管道命令,每一段都單獨寫在一行中,增加可讀性
    tr ‘+-=*.,;:{}()#!?<>"\n\t‘ ‘ ‘ < $1 |     #把所有大小寫字母轉換為小寫字母
    tr ‘A-Z‘ ‘a-z‘ |     #把連續重復的空格符替換為一個空格符
    tr -s ‘ ‘ |     #把空格符轉換為換行符
    tr ‘ ‘ ‘\n‘ |     #把相同的單詞放到一起
    sort |     #刪除重復單詞,並進行統計
    uniq -c |     #根據重復的次數進行排序
    sort -rn

}

echo
echo "This script can count words of aspecified file."

#使用空命令冒號構建無限循環
while :
do

    read -p "Enter the file path(or quit):"
    case "$REPLY" in
    [Qq] |[Qq][Uu][Ii][Tt])
            echo "Bye."
            #在輸入大、小寫quit時,退出
            exit 0
            ;;
    *)
            #判斷輸入的時一個可讀的普通文件,並且內容不為空
            if [ -f "$REPLY" ] && [ -r "$REPLY" ] && [ -s "$REPLY" ]
            then
                    #當用戶輸入一個合法文件時
                    #調用count函數統計文件的單詞個數
                    count "$REPLY"
            else
                    #如果輸入了非法文件,顯示不能處理它
                    echo "$REPLY can not be dealed with."
            fi
            ;;
    esac

done
exit 0

## 運行結果

[root@akuilinux01 shellXT]# sh count_words.sh

This script can count words of aspecified file.
Enter the file path(or quit):/tmp/shellXT/words.txt
5 name
5 is
4 my
3 akui
1 akui][my
1 akui\
Enter the file path(or quit):


## 討論
- uniq命令可以統計多個相同行中的一行,-c選項用來統計相鄰行的重復次數,在本題中可以使用uniq -c命令統計每一個單詞的重復次數,但前提是讓每一個單詞都占用單獨的一行
- 要把每個單詞單詞單獨放一行,需要先把所有的單詞(包括相同的行和相同的單詞)緊密的連接在一起
- tr命令可以轉換或刪除輸入數據中的字符,使用tr命令把文件中的特殊符號轉換為空格符,再把大寫字母轉換為小寫,為了避免多個空格影響空行的統計,還需要把重復的空格符轉換為一個空格符,最後還需要把所有的空格符轉換為換行符,這樣就把每一個單詞都單獨放在一行中
- 再通過sort命令把相同的單詞放到一起
- 這樣就能使用uniq -c命令統計出每個單詞的次數了
- 最後在用sort -rn從大到小排序
- 為了能讓腳本有更加清晰的模塊結構,我們把關鍵的操作定義在count()函數中。腳本執行以後,首先會打印一些信息告訴用戶腳本的作用,然後會執行while循環不停的接受用戶輸入的路徑。
- while語句測試的條件為bash的內建命令:。冒號命令是一個空命令,它不會做任何事情並且永遠返回真,這樣while循環是一個無限循環,會不停的詢問用戶所要統計的文件。在循環體中通過read命令得到用戶的輸入,並通過case語句的匹配功能判斷用戶是否輸入了字符q或字符串quit,如果是則執行exit命令退出腳本,否則腳本會把這個輸入的字符串當成文件路徑。
- 通過if語句檢測是否存在這樣的一個可讀文件,如果存在就以這個路徑作為參數,調用函數count()來統計文件中的單詞個數,如果不存在就顯示相應信息並進入下一次while循環,重復之前的步驟
- 假如用戶輸入了一個合法的文件,則腳本會以這個文件的路徑作為參數調用函數count。在函數體中首先檢查函數調用時是否指定了參數,即測試特殊變量$#是否等於1,如果沒有指定參數,腳本會輸出錯誤信息並直接終止運行,如果以一個文件路徑作為參數調用count函數,這個文件路徑會被保存在位置變量$1中,可以看到第一個tr命令通過標準輸入重定向從$1中讀取文件的數據。

文本操作4(tr,sort,unip)