码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-03-25 21:45:28      阅读:199      评论:0      收藏:0      [点我收藏+]

标签: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)

标签:tr   sort   uniq   

原文地址:http://blog.51cto.com/akui2521/2090958

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!