bash shell学习-实践 (自己实现一些小工具)

  The poor starve while the rich feast.

  "穷人饥肠辘辘,富人大吃大喝"

 

参考资料鸟哥的Linux私房菜 基础学习篇(第三版) 

       Linux Shell脚本攻略 

         Linux程序设计(第四版)

 

一、简易单词管理程序

  简介: 本程序主要用于记录和查询英文单词信息,可能没有什么实际用途,也可能代码中有一些不太简洁的实现,主要是因为编写本程序的目的是为了熟练一下shell script编程的基础知识

  功能: ①单词查询; ②单个单词导入词库; ③从文件导入词库;④统计词库信息;

  程序结构: 一个Bash shell程序 explain (解释), 一个词库文件: .word_lib.txt , 保存在用户家目录下的  .word_manager 目录中

  文件内容:  .word_lib.txt 是词库文件,保存所有单词信息, 每行一个单词, 包括: 原型, 中文意思。所有单词信息已经过排序去重处理; 

  程序执行流程: 解析命令选项-->根据解析结果执行对应的操作-->退出程序

  程序介绍:

 1 用法: explain [-afcb] [单词|文件名] [单词信息]
 2 选项: 
 3   不带选项: 查询单词并打印出查询结果,结果格式: word  中文意思
 4   -a  : 将单词信息导入词库,后跟单词和单词信息
 5   -f  : 从文件导入词库,后跟文件名
 6   -c  : 统计词库中的单词总数
 7   -b  : 浏览词库的单词信息(通过more命令打开)

8 所有正确的命令格式: 9   explain word #查询word指定的单词 10   explain -c   #打印出词库当前共有多少个单词 11   explain -b   #浏览词库的单词信息 12   explain -a word wordinfo #添加单词信息至词库 13   explain -f filename    #将文件导入词库,要求格式一致 14 15 说明:word可以为英文单词,也可以为中文,只要词库中某一行包含word,就会打印出该行,所以查询结果可能包含多行
16 退出码: 17   0 :程序执行成功 18   1 :没有输入选项和参数 19   2 :输入了未知的选项 20   3 :-a后面没有跟着单词和解释 21   4 :-f后面没有文件名或者是不存在的文件

  源码如下:

  1 #/bin/bash - 
  2 #===============================================================================
  3 #
  4 #          FILE: explain.sh
  5 # 
  6 #         USAGE: ./explain.sh 
  7 # 
  8 #   DESCRIPTION: 简易单词管理程序
  9 # 
 10 #       OPTIONS: ---
 11 #  REQUIREMENTS: ---
 12 #          BUGS: ---
 13 #         NOTES: ---
 14 #        AUTHOR: Aut (yinjing), autyinjing@126.com
 15 #  ORGANIZATION: 
 16 #       CREATED: 2015年06月29日 16:23
 17 #      REVISION:  ---
 18 #===============================================================================
 19 
 20 # 1 可执行文件的查找路径设置
 21 PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
 22 export PATH
 23 
 24 # 2 相关的全局变量声明和设置
 25 home_path=~/.word_manager               #相关文件的主目录
 26 lib_path=$home_path/.word_lib.txt       #词库文件的路径
 27 
 28 # 3 相关目录和文件的设置
 29 if [ ! -d "$home_path" ]; then
 30         mkdir $home_path        #~/.word_manager
 31         touch $lib_path         #~/.word_manager/.word_lib.txt
 32 fi
 33 
 34 # 4 相关函数实现
 35 function query()                #直接查询单词信息
 36 {
 37         ret=$(cat $lib_path | grep "$1")
 38         if [ -z "$ret" ]; then
 39                 echo "$1 not be found!"
 40         else
 41                 echo "$ret"
 42         fi
 43 }
 44 
 45 function update_lib()           #对词库进行排序去重,目前还没有想到更好的方法,只能利用临时文件
 46 {
 47         cat $lib_path | sort -fb | uniq > ~/.word_manager/._word_lib.txt
 48         rm $lib_path
 49         mv ~/.word_manager/._word_lib.txt $lib_path
 50 }
 51 
 52 function print_count()
 53 {
 54         ret=$(wc -l $lib_path | cut -d ' ' -f1 | grep '[[:digit:]]')
 55         echo "当前词库共有$ret个单词"
 56 }
 57 
 58 function add_to_lib()           #添加单词到词库
 59 {
 60         word=$1\ $2             #将新的单词信息保存为一整行
 61         echo "$word" >> $lib_path    #~/.word_manager/.word_lib.txt
 62         update_lib
 63         echo "成功将 $word 导入词库!"
 64         print_count
 65 }
 66 
 67 function add_from_file()        #通过文件导入词库
 68 {
 69         cat $1 >> $lib_path     #~/.word_manager/.word_lib.txt
 70         update_lib
 71         echo "成功将 $1 内的单词导入词库!"
 72         print_count
 73 }
 74 
 75 function browse_lib()
 76 {
 77         echo ""
 78         more $lib_path
 79         echo ""
 80         print_count
 81 }
 82 
 83 function print_help()
 84 {
 85         echo ""
 86         echo "用法: explain [选项] [单词|文件名] [单词信息]"
 87         echo ""
 88         echo "选项:"
 89         echo "  不带选项: 查询单词并打印出查询结果"
 90         echo "  -a     : 将单词信息导入词库,后跟单词和单词信息"
 91         echo "  -f     : 从文件导入词库,后跟要导入的文件名"
 92         echo "  -c     : 统计词库中的单词总数"
 93         echo "  -b     : 浏览词库中单词信息"
 94         echo "  --help : 显示帮助信息"
 95         echo ""
 96 }
 97 
 98 # 5 主程序部分
 99 if [ "$#" -lt 1 ]; then         #首先判断命令格式是否正确
100         print_help
101         exit 1
102 fi
103 
104 opt=$(echo $* | cut -d ' ' -f1 | grep '^-')     #解析选项
105 case $opt in
106         "")
107                 query $1
108                 ;;
109         "-a")
110                 if [ "$#" -eq "3" ]; then
111                         add_to_lib $2 $3
112                 else
113                         echo "正确格式:explain -a word wordinfo"
114                         exit 3
115                 fi
116                 ;;
117         "-f")
118                 if [ -f "$2" ]; then
119                         add_from_file $2
120                 else
121                         echo "不存在的文件 $2"
122                         exit 4
123                 fi
124                 ;;
125         "-c")
126                 print_count
127                 ;;
128         "-b")
129                 browse_lib
130                 ;;
131         "--help")
132                 print_help
133                 ;;
134         *)
135                 echo "未知的选项,输入 explain --help 查看帮助信息"
136                 exit 2
137 esac
138 
139 exit 0
View Code

  使用截图如下,笔者已增加了文件的可执行权限并复制到/usr/bin/,所以可以直接输入程序名来执行命令

  空的词库:(不知道为什么图片和文字之间的间隔那么大,并没有空行~~)

  添加单个单词: 

  从文件导入词库:

  查询:

  篇幅有限,错误的命令提示就不发图了

 

二、回文串检测程序

  程序说明:本程序用于检测一个文件内的回文单词,并将所有回文单词按照每个一行的格式打印出来

1 用法:match_plalindrome filename
2 输出:按照单词长度递增的顺序打印出所有的回文单词(默认检测长度在3~20之间的单词)
3 核心思想:用正则表达式中的'(.)'匹配任意字符,再用反向引用 '...\2\1' 匹配前面的任意字符达到检测回文串的目的,详细内容参见下面源码
4 说明:程序默认将 空格、,、.、?、:、! 作为单词分隔符

  程序源码:

 1 #!/bin/bash - 
 2 #===============================================================================
 3 #
 4 #          FILE: match_plalindrome.sh
 5 # 
 6 #         USAGE: ./match_plalindrome.sh 
 7 # 
 8 #   DESCRIPTION: 
 9 # 
10 #       OPTIONS: ---
11 #  REQUIREMENTS: ---
12 #          BUGS: ---
13 #         NOTES: ---
14 #        AUTHOR: Aut (yinjing), autyinjing@126.com
15 #  ORGANIZATION: 
16 #       CREATED: 2015年06月30日 19:13
17 #      REVISION:  ---
18 #===============================================================================
19 
20 # 1 判断命令格式是否正确
21 if [ "$#" -ne 1 ];
22 then
23         echo "Usage: $0 filename"
24         exit 1
25 fi
26 
27 # 2 全局变量的声明和设置
28 filename=$1             #要查找的文件名
29 tmpfile=tmp.txt         #临时文件的文件名
30 declare -i count        #回文串的重复部分长度
31 
32 # 3 由于原文件中的内容可能不是每行一个单词,所以这里要使用一个临时文件将原文件的信息转换为每行一个单词
33 cat $filename | tr '[ ,.?:!]' '\n' > $tmpfile    #将所有的标点符号及空格替换为换行符
34 sed -i '/^$/d' $tmpfile         #删除所有空行
35 
36 # 4 默认查找长度为3到20的回文串
37 for ((len=3; len<=20; len++))   #循环查找各个长度的回文串
38 do
39         basepattern='/^\(.\)'   #基础模式
40         count=$(( $len / 2 ))   #计算重复部分的长度
41         
42         for ((i=1; i<$count; i++))      #设置正则表达式
43         do
44                 basepattern=$basepattern'\(.\)'
45         done
46 
47         if [ $(( $len % 2 )) -ne 0 ];     #判断字符串长度是奇数还是偶数并设置对称轴
48         then
49                 basepattern=$basepattern'.'
50         fi
51 
52         for ((count; count>0; count--)) #设置反向引用
53         do
54                 basepattern=$basepattern'\'"$count"
55         done
56 
57         basepattern=$basepattern'$/p'   #添加打印参数
58 
59         sed -n "$basepattern" $tmpfile
60 done
61 
62 # 5 删除临时文件
63 rm $tmpfile
64 
65 exit 0
View Code

  运行截图:

三、其他命令(持续更新...)

  1、用awk实现head

1 $ awk 'NR <= 10' filename   
2 说明:打印行号小于等于10的行

  2、用awk实现tail

1 $ awk '{ buffer[NR % 10] = $0; } END { for (i=1;i<11;i++) { print buffer[i%10] } }' filename   
2 说明:用数组保存文件的最后10行,然后打印

  3、用awk实现tac

1 $ awk '{ buffer[NR] = $0; } END { for (i=NR; i>0; i--) { print buffer[i] } }'  
2 说明:顺序保存,然后逆序打印

 

总结:刚开始学写脚本,感觉一切好神奇,实现一点简单的功能都好牛X,呵呵~~以后一定多多加油

posted @ 2015-07-01 21:09  Aut  阅读(400)  评论(0编辑  收藏  举报