[toc]
#课程目标

  • 掌握case语句的基本语法结构
  • 掌握函数的定义及调用
  • 掌握常用的正则表达式元字符含义

一、case语句

关键词:确认过眼神,你是对的人CASE语句+函数+正则 - 图1

  1. case语句为多重匹配语句
  2. 如果匹配成功,执行相匹配的命令

1. 语法结构

  1. 说明:pattern表示需要匹配的模式
  2. case var in 定义变量;var代表是变量名
  3. pattern 1) 模式1;用 | 分割多个模式,相当于or
  4. command1 需要执行的语句
  5. ;; 两个分号代表命令结束
  6. pattern 2)
  7. command2
  8. ;;
  9. pattern 3)
  10. command3
  11. ;;
  12. *) default,不满足以上模式,默认执行*)下面的语句
  13. command4
  14. ;;
  15. esac esac表示case语句结束

2. 应用案例

㈠ 脚本传不同值做不同事

具体需求:当给程序传入start、stop、restart三个不同参数时分别执行相应命令

  1. #!/bin/env bash
  2. case $1 in
  3. start|S)
  4. service apache start &>/dev/null && echo "apache 启动成功"
  5. ;;
  6. stop|T)
  7. service apache stop &>/dev/null && echo "apache 停止成功"
  8. ;;
  9. restart|R)
  10. service apache restart &>/dev/null && echo "apache 重启完毕"
  11. ;;
  12. *)
  13. echo "请输入要做的事情..."
  14. ;;
  15. esac

㈡ 根据用户需求选择做事

具体需求:

脚本提示让用户输入需要管理的服务名,然后提示用户需要对服务做什么操作,如启动,关闭等操作

  1. #!/bin/env bash
  2. read -p "请输入你要管理的服务名称(vsftpd):" service
  3. case $service in
  4. vsftpd|ftp)
  5. read -p "请选择你需要做的事情(restart|stop):" action
  6. case $action in
  7. stop|S)
  8. service vsftpd stop &>/dev/null && echo "该$serivce服务已经停止成功"
  9. ;;
  10. start)
  11. service vsftpd start &>/dev/null && echo "该$serivce服务已经成功启动"
  12. ;;
  13. esac
  14. ;;
  15. httpd|apache)
  16. echo "apache hello world"
  17. ;;
  18. *)
  19. echo "请输入你要管理的服务名称(vsftpd)"
  20. ;;
  21. esac

㈢ 菜单提示让用户选择需要做的事

具体需求:

模拟一个多任务维护界面;当执行程序时先显示总菜单,然后进行选择后做相应维护监控操作

  1. **********请选择*********
  2. h 显示命令帮助
  3. f 显示磁盘分区
  4. d 显示磁盘挂载
  5. m 查看内存使用
  6. u 查看系统负载
  7. q 退出程序
  8. *************************

思路:

  1. 菜单打印出来
  2. 交互式让用户输入操作编号,然后做出相应处理

落地实现:

  1. 菜单打印(分解动作)
  1. #!/bin/env bash
  2. cat <<-EOF
  3. h 显示命令帮助
  4. f 显示磁盘分区
  5. d 显示磁盘挂载
  6. m 查看内存使用
  7. u 查看系统负载
  8. q 退出程序
  9. EOF
  1. 最终实现
  1. #!/bin/bash
  2. #打印菜单
  3. cat <<-EOF
  4. h 显示命令帮助
  5. f 显示磁盘分区
  6. d 显示磁盘挂载
  7. m 查看内存使用
  8. u 查看系统负载
  9. q 退出程序
  10. EOF
  11. #让用户输入需要的操作
  12. while true
  13. do
  14. read -p "请输入需要操作的选项[f|d]:" var1
  15. case $var1 in
  16. h)
  17. cat <<-EOF
  18. h 显示命令帮助
  19. f 显示磁盘分区
  20. d 显示磁盘挂载
  21. m 查看内存使用
  22. u 查看系统负载
  23. q 退出程序
  24. EOF
  25. ;;
  26. f)
  27. fdisk -l
  28. ;;
  29. d)
  30. df -h
  31. ;;
  32. m)
  33. free -m
  34. ;;
  35. u)
  36. uptime
  37. ;;
  38. q)
  39. exit
  40. ;;
  41. esac
  42. done
  43. #!/bin/bash
  44. #打印菜单
  45. menu(){
  46. cat <<-END
  47. h 显示命令帮助
  48. f 显示磁盘分区
  49. d 显示磁盘挂载
  50. m 查看内存使用
  51. u 查看系统负载
  52. q 退出程序
  53. END
  54. }
  55. menu
  56. while true
  57. do
  58. read -p "请输入你的操作[h for help]:" var1
  59. case $var1 in
  60. h)
  61. menu
  62. ;;
  63. f)
  64. read -p "请输入你要查看的设备名字[/dev/sdb]:" var2
  65. case $var2 in
  66. /dev/sda)
  67. fdisk -l /dev/sda
  68. ;;
  69. /dev/sdb)
  70. fdisk -l /dev/sdb
  71. ;;
  72. esac
  73. ;;
  74. d)
  75. lsblk
  76. ;;
  77. m)
  78. free -m
  79. ;;
  80. u)
  81. uptime
  82. ;;
  83. q)
  84. exit
  85. ;;
  86. esac
  87. done

课堂练习:

  1. 输入一个等级(A-E),查看每个等级的成绩;如:输入A,则显示“90分~100分”,依次类推
  2. 判断用户输入的字符串,如果是”hello”,则显示”world”;如果是”world”,则显示”hello”,否则提示”请输入hello或者world,谢谢!”

二、函数

1. 什么是函数?

  • shell中允许将一组命令集合语句形成一段可用代码,这些代码块称为shell函数
  • 给这段代码起个名字称为函数名,后续可以直接调用该段代码的功能

2. 如何定义函数?

方法1:

  1. 函数名()
  2. {
  3. 函数体(一堆命令的集合,来实现某个功能)
  4. }

方法2:

  1. function 函数名()
  2. {
  3. 函数体(一堆命令的集合,来实现某个功能)
  4. echo hello
  5. echo world
  6. }

函数中return说明:

  1. return可以结束一个函数。类似于循环控制语句break(结束当前循环,执行循环体后面的代码)。
  2. return默认返回函数中最后一个命令状态值,也可以给定参数值,范围是0-256之间。
  3. 如果没有return命令,函数将返回最后一个指令的退出状态值。

3. 函数如何调用?

㈠ 当前命令行调用

  1. [root@MissHou shell04]# cat fun1.sh
  2. #!/bin/bash
  3. hello(){
  4. echo "hello lilei $1"
  5. hostname
  6. }
  7. menu(){
  8. cat <<-EOF
  9. 1. mysql
  10. 2. web
  11. 3. app
  12. 4. exit
  13. EOF
  14. }
  15. [root@MissHou shell04]# source fun1.sh
  16. [root@MissHou shell04]# . fun1.sh
  17. [root@MissHou shell04]# hello 888
  18. hello lilei 888
  19. MissHou.itcast.cc
  20. [root@MissHou shell04]# menu
  21. 1. mysql
  22. 2. web
  23. 3. app
  24. 4. exit

㈡ 定义到用户的环境变量中

  1. [root@MissHou shell05]# vim ~/.bashrc
  2. 文件中增加如下内容:
  3. hello(){
  4. echo "hello lilei $1"
  5. hostname
  6. }
  7. menu(){
  8. cat <<-EOF
  9. 1. mysql
  10. 2. web
  11. 3. app
  12. 4. exit
  13. EOF
  14. }
  15. 注意:
  16. 当用户打开bash的时候会读取该文件

㈢ 脚本中调用

  1. #!/bin/bash
  2. #打印菜单
  3. source ./fun1.sh
  4. menu(){
  5. cat <<-END
  6. h 显示命令帮助
  7. f 显示磁盘分区
  8. d 显示磁盘挂载
  9. m 查看内存使用
  10. u 查看系统负载
  11. q 退出程序
  12. END
  13. }
  14. menu //调用函数

4. 应用案例

具体需求:

  1. 写一个脚本收集用户输入的基本信息(姓名,性别,年龄),如不输入一直提示输入
  2. 最后根据用户的信息输出相对应的内容

思路:

  1. 交互式定义多个变量来保存用户信息 姓名、性别、年龄
  2. 如果不输一直提示输入
    • 循环直到输入字符串不为空 while 判断输入字符串是否为空
    • 每个信息都必须不能为空,该功能可以定义为一个函数,方便下面脚本调用
  3. 根据用户输入信息做出匹配判断

代码实现:

  1. #!/bin/bash
  2. #该函数实现用户如果不输入内容则一直循环直到用户输入为止,并且将用户输入的内容打印出来
  3. input_fun()
  4. {
  5. input_var=""
  6. output_var=$1
  7. while [ -z $input_var ]
  8. do
  9. read -p "$output_var" input_var
  10. done
  11. echo $input_var
  12. }
  13. input_fun 请输入你的姓名:
  14. 或者
  15. #!/bin/bash
  16. fun()
  17. {
  18. read -p "$1" var
  19. if [ -z $var ];then
  20. fun $1
  21. else
  22. echo $var
  23. fi
  24. }
  25. #调用函数并且获取用户的姓名、性别、年龄分别赋值给name、sex、age变量
  26. name=$(input_fun 请输入你的姓名:)
  27. sex=$(input_fun 请输入你的性别:)
  28. age=$(input_fun 请输入你的年龄:)
  29. #根据用户输入的性别进行匹配判断
  30. case $sex in
  31. man)
  32. if [ $age -gt 18 -a $age -le 35 ];then
  33. echo "中年大叔你油腻了吗?加油"
  34. elif [ $age -gt 35 ];then
  35. echo "保温杯里泡枸杞"
  36. else
  37. echo "年轻有为。。。"
  38. fi
  39. ;;
  40. woman)
  41. xxx
  42. ;;
  43. *)
  44. xxx
  45. ;;
  46. esac

扩展延伸:

  1. 描述以下代码含义:
  2. :()
  3. {
  4. :|:&
  5. }
  6. :

三、综合案例

1. 任务背景

现有的跳板机虽然实现了统一入口来访问生产服务器,yunwei用户权限太大可以操作跳板机上的所有目录文件,存在数据被误删的安全隐患,所以希望你做一些安全策略来保证跳板机的正常使用。

2. 具体要求

  1. 只允许yunwei用户通过跳板机远程连接后台的应用服务器做一些维护操作
  2. 公司运维人员远程通过yunwei用户连接跳板机时,跳出以下菜单供选择:
  1. 欢迎使用Jumper-server,请选择你要操作的主机:
  2. 1. DB1-Master
  3. 2. DB2-Slave
  4. 3. Web1
  5. 4. Web2
  6. h. help
  7. q. exit
  1. 当用户选择相应主机后,直接免密码登录成功
  2. 如果用户不输入一直提示用户输入,直到用户选择退出

3. 综合分析

  1. 将脚本放到yunwei用户家目录里的.bashrc文件里(/shell05/jumper-server.sh)
  2. 将菜单定义为一个函数[打印菜单],方便后面调用
  3. 用case语句来实现用户的选择【交互式定义变量】
  4. 当用户选择了某一台服务器后,进一步询问用户需要做的事情 case…esac 交互式定义变量
  5. 使用循环来实现用户不选择一直让其选择
  6. 限制用户退出后直接关闭终端 exit

4. 落地实现

  1. #!/bin/bash
  2. # jumper-server
  3. # 定义菜单打印功能的函数
  4. menu()
  5. {
  6. cat <<-EOF
  7. 欢迎使用Jumper-server,请选择你要操作的主机:
  8. 1. DB1-Master
  9. 2. DB2-Slave
  10. 3. Web1
  11. 4. Web2
  12. h. help
  13. q. exit
  14. EOF
  15. }
  16. # 屏蔽以下信号
  17. trap '' 1 2 3 19
  18. # 调用函数来打印菜单
  19. menu
  20. #循环等待用户选择
  21. while true
  22. do
  23. # 菜单选择,case...esac语句
  24. read -p "请选择你要访问的主机:" host
  25. case $host in
  26. 1)
  27. ssh root@10.1.1.1
  28. ;;
  29. 2)
  30. ssh root@10.1.1.2
  31. ;;
  32. 3)
  33. ssh root@10.1.1.3
  34. ;;
  35. h)
  36. clear;menu
  37. ;;
  38. q)
  39. exit
  40. ;;
  41. esac
  42. done
  43. 将脚本放到yunwei用户家目录里的.bashrc里执行:
  44. bash ~/jumper-server.sh
  45. exit

进一步完善需求

为了进一步增强跳板机的安全性,工作人员通过跳板机访问生产环境,但是不能在跳板机上停留。

  1. #!/bin/bash
  2. #公钥推送成功
  3. trap '' 1 2 3 19
  4. #打印菜单用户选择
  5. menu(){
  6. cat <<-EOF
  7. 欢迎使用Jumper-server,请选择你要操作的主机:
  8. 1. DB1-Master
  9. 2. DB2-Slave
  10. 3. Web1
  11. 4. Web2
  12. h. help
  13. q. exit
  14. EOF
  15. }
  16. #调用函数来打印菜单
  17. menu
  18. while true
  19. do
  20. read -p "请输入你要选择的主机[h for help]:" host
  21. #通过case语句来匹配用户所输入的主机
  22. case $host in
  23. 1|DB1)
  24. ssh root@10.1.1.1
  25. ;;
  26. 2|DB2)
  27. ssh root@10.1.1.2
  28. ;;
  29. 3|web1)
  30. ssh root@10.1.1.250
  31. ;;
  32. h|help)
  33. clear;menu
  34. ;;
  35. q|quit)
  36. exit
  37. ;;
  38. esac
  39. done
  40. 自己完善功能:
  41. 1. 用户选择主机后,需要事先推送公钥;如何判断公钥是否已推
  42. 2. 比如选择web1时,再次提示需要做的操作,比如:
  43. clean log
  44. 重启服务
  45. kill某个进程

回顾信号:

  1. 1) SIGHUP 重新加载配置
  2. 2) SIGINT 键盘中断^C
  3. 3) SIGQUIT 键盘退出
  4. 9) SIGKILL 强制终止
  5. 15) SIGTERM 终止(正常结束),缺省信号
  6. 18) SIGCONT 继续
  7. 19) SIGSTOP 停止
  8. 20) SIGTSTP 暂停^Z

四、正则表达式

1. 正则表达式是什么?

正则表达式(Regular Expression、regex或regexp,缩写为RE),也译为正规表示法、常规表示法,是一种字符模式,用于在查找过程中匹配指定的字符。

许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。

正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的。

支持正则表达式的程序如:locate |find| vim| grep| sed |awk

2. 正则能干什么?

  1. 匹配邮箱、匹配身份证号码、手机号、银行卡号等
  2. 匹配某些特定字符串,做特定处理等等

3. 正则当中名词解释

  • 元字符
    指那些在正则表达式中具有特殊意义的专用字符,如:点(.) 星(*) 问号(?)等
  • 前导字符
    位于元字符前面的字符. abc* aooo.

4. 第一类正则表达式

㈠ 正则中普通常用的元字符

元字符 功能 备注
. 匹配除了换行符以外的任意单个字符
* 前导字符出现0次或连续多次
.* 任意长度字符 ab.*
^ 行首(以…开头) ^root
$ 行尾(以…结尾) bash$
^$ 空行
[] 匹配括号里任意单个字符或一组单个字符 [abc]
[^] 匹配不包含括号里任一单个字符或一组单个字符 [^abc]
[1] 匹配以括号里任意单个字符或一组单个字符开头 [2]
^[^] 匹配不以括号里任意单个字符或一组单个字符开头 ^[^abc]
  • 示例文本
  1. # cat 1.txt
  2. ggle
  3. gogle
  4. google
  5. gooogle
  6. goooooogle
  7. gooooooogle
  8. taobao.com
  9. taotaobaobao.com
  10. jingdong.com
  11. dingdingdongdong.com
  12. 10.1.1.1
  13. Adfjd8789JHfdsdf/
  14. a87fdjfkdLKJK
  15. 7kdjfd989KJK;
  16. bSKJjkksdjf878.
  17. cidufKJHJ6576,
  18. hello world
  19. helloworld yourself
  • 举例说明

㈡ 正则中其他常用元字符

元字符 功能 备注
\< 取单词的头
\> 取单词的尾
\< \> 精确匹配
\{n\} 匹配前导字符连续出现n次
\{n,\} 匹配前导字符至少出现n次
\{n,m\} 匹配前导字符出现n次与m次之间
\( \) 保存被匹配的字符
\d 匹配数字(grep -P [0-9]
\w 匹配字母数字下划线(grep -P [a-zA-Z0-9_]
\s 匹配空格、制表符、换页符(grep -P [\t\r\n]

举例说明:

  1. 需求:将10.1.1.1替换成10.1.1.254
  2. 1vim编辑器支持正则表达式
  3. # vim 1.txt
  4. :%s#\(10.1.1\).1#\1.254#g
  5. :%s/\(10.1.1\).1/\1.254/g
  6. 2sed支持正则表达式【后面学】
  7. # sed -n 's#\(10.1.1\).1#\1.254#p' 1.txt
  8. 10.1.1.254
  9. 说明:
  10. 找出含有10.1.1的行,同时保留10.1.1并标记为标签1,之后可以使用\1来引用它。
  11. 最多可以定义9个标签,从左边开始编号,最左边的是第一个。
  12. 需求:将helloworld yourself 换成hellolilei myself
  13. # vim 1.txt
  14. :%s#\(hello\)world your\(self\)#\1lilei my\2#g
  15. # sed -n 's/\(hello\)world your\(self\)/\1lilei my\2/p' 1.txt
  16. hellolilei myself
  17. # sed -n 's/helloworld yourself/hellolilei myself/p' 1.txt
  18. hellolilei myself
  19. # sed -n 's/\(hello\)world your\(self\)/\1lilei my\2/p' 1.txt
  20. hellolilei myself
  21. Perl内置正则:
  22. \d 匹配数字 [0-9]
  23. \w 匹配字母数字下划线[a-zA-Z0-9_]
  24. \s 匹配空格、制表符、换页符[\t\r\n]
  25. # grep -P '\d' 1.txt
  26. # grep -P '\w' 2.txt
  27. # grep -P '\s' 3.txt

㈢ 扩展类正则常用元字符

丑话说在前面:

我说我比较特殊,你要相信!否则我错给你看CASE语句+函数+正则 - 图2

  • grep你要用我,必须加 -E 或者 让你兄弟egrep来找我
  • sed你要用我,必须加 -r | 扩展元字符 | 功能 | 备注 | | —- | —- | —- | | + | 匹配一个或多个前导字符 | bo+ 匹配boo、 bo | | ? | 匹配零个或一个前导字符 | bo? 匹配b、 bo | | | | 或 | 匹配a或b | | () | 组字符(看成整体) | (my|your)self:表示匹配myself或匹配yourself | | {n} | 前导字符重复n次 | | | {n,} | 前导字符重复至少n次 | | | {n,m} | 前导字符重复n到m次 | |

举例说明:

  1. # grep "root|ftp|adm" /etc/passwd
  2. # egrep "root|ftp|adm" /etc/passwd
  3. # grep -E "root|ftp|adm" /etc/passwd
  4. # grep -E 'o+gle' test.txt
  5. # grep -E 'o?gle' test.txt
  6. # egrep 'go{2,}' 1.txt
  7. # egrep '(my|your)self' 1.txt
  8. 使用正则过滤出文件中的IP地址:
  9. # grep '[0-9]\{2\}\.[0-9]\{1\}\.[0-9]\{1\}\.[0-9]\{1\}' 1.txt
  10. 10.1.1.1
  11. # grep '[0-9]{2}\.[0-9]{1}\.[0-9]{1}\.[0-9]{1}' 1.txt
  12. # grep -E '[0-9]{2}\.[0-9]{1}\.[0-9]{1}\.[0-9]{1}' 1.txt
  13. 10.1.1.1
  14. # grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' 1.txt
  15. 10.1.1.1
  16. # grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}' 1.txt
  17. 10.1.1.1

5. 第二类正则

表达式 功能 示例
[:alnum:] 字母与数字字符 [[:alnum:]]+
[:alpha:] 字母字符(包括大小写字母) [[:alpha:]]{4}
[:blank:] 空格与制表符 [[:blank:]]*
[:digit:] 数字 [[:digit:]]?
[:lower:] 小写字母 [[:lower:]]{4,}
[:upper:] 大写字母 [[:upper:]]+
[:punct:] 标点符号 [[:punct:]]
[:space:] 包括换行符,回车等在内的所有空白 [[:space:]]+
  1. [root@server shell05]# grep -E '^[[:digit:]]+' 1.txt
  2. [root@server shell05]# grep -E '^[^[:digit:]]+' 1.txt
  3. [root@server shell05]# grep -E '[[:lower:]]{4,}' 1.txt

6. 正则表达式总结

把握一个原则,让你轻松搞定可恶的正则符号:

  1. 我要找什么?
    • 找数字 [0-9]
    • 找字母 [a-zA-Z]
    • 找标点符号 [[:punct:]]
  2. 我要如何找?看心情找
    • 以什么为首 ^key
    • 以什么结尾 key$
    • 包含什么或不包含什么 [abc] ^[abc] [^abc] ^[^abc]
  3. 我要找多少呀?
    • 找前导字符出现0次或连续多次 ab==*==
    • 找任意单个(一次)字符 ab==.==
    • 找任意字符 ab==.*==
    • 找前导字符连续出现几次 {n} {n,m} {n,}
    • 找前导字符出现1次或多次 go==+==
    • 找前到字符出现0次或1次 go==?==

五、正则元字符一栏表

元字符:在正则中,具有特殊意义的专用字符,如: 星号(*)、加号(+)等

前导字符:元字符前面的字符叫前导字符

元字符 功能 示例
* 前导字符出现0次或者连续多次 ab* abbbb
. 除了换行符以外,任意单个字符 ab. ab8 abu
.* 任意长度的字符 ab.* adfdfdf
[] 括号里的任意单个字符或一组单个字符 [abc][0-9][a-z]
[^] 不匹配括号里的任意单个字符或一组单个字符 [^abc]
[3] 匹配以括号里的任意单个字符开头 [4]
^[^] 不匹配以括号里的任意单个字符开头
^ 行的开头 ^root
$ 行的结尾 bash$
^$ 空行
\{n\}和{n} 前导字符连续出现n次 [0-9]\{3\}
\{n,\}和{n,} 前导字符至少出现n次 [a-z]{4,}
\{n,m\}和{n,m} 前导字符连续出现n-m次 go{2,4}
\<\> 精确匹配单词 \
\(\) 保留匹配到的字符 \(hello\)
+ 前导字符出现1次或者多次 [0-9]+
? 前导字符出现0次或者1次 go?
| ^root|^ftp
() 组字符 (hello|world)123
\d perl内置正则 grep -P \d+
\w 匹配字母数字下划线

六、正则练习作业

1. 文件准备

  1. # vim test.txt
  2. Aieur45869Root0000
  3. 9h847RkjfkIIIhello
  4. rootHllow88000dfjj
  5. 8ikuioerhfhupliooking
  6. hello world
  7. 192.168.0.254
  8. welcome to uplooking.
  9. abcderfkdjfkdtest
  10. rlllA899kdfkdfj
  11. iiiA848890ldkfjdkfj
  12. abc
  13. 12345678908374
  14. 123456@qq.com
  15. 123456@163.com
  16. abcdefg@itcast.com23ed

2. 具体要求

  1. 1、查找不以大写字母开头的行(三种写法)。
  2. grep '^[^A-Z]' 2.txt
  3. grep -v '^[A-Z]' 2.txt
  4. grep '^[^[:upper:]]' 2.txt
  5. 2、查找有数字的行(两种写法)
  6. grep '[0-9]' 2.txt
  7. grep -P '\d' 2.txt
  8. 3、查找一个数字和一个字母连起来的
  9. grep -E '[0-9][a-zA-Z]|[a-zA-Z][0-9]' 2.txt
  10. 4、查找不以r开头的行
  11. grep -v '^r' 2.txt
  12. grep '^[^r]' 2.txt
  13. 5、查找以数字开头的
  14. grep '^[0-9]' 2.txt
  15. 6、查找以大写字母开头的
  16. grep '^[A-Z]' 2.txt
  17. 7、查找以小写字母开头的
  18. grep '^[a-z]' 2.txt
  19. 8、查找以点结束的
  20. grep '\.$' 2.txt
  21. 9、去掉空行
  22. grep -v '^$' 2.txt
  23. 10、查找完全匹配abc的行
  24. grep '\<abc\>' 2.txt
  25. 11、查找A后有三个数字的行
  26. grep -E 'A[0-9]{3}' 2.txt
  27. grep 'A[0-9]\{3\}' 2.txt
  28. 12、统计root在/etc/passwd里出现了几次
  29. grep -o 'root' 1.txt |wc -l
  30. 13、用正则表达式找出自己的IP地址、广播地址、子网掩码
  31. ifconfig eth0|grep Bcast|grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
  32. ifconfig eth0|grep Bcast| grep -E -o '([0-9]{1,3}.){3}[0-9]{1,3}'
  33. ifconfig eth0|grep Bcast| grep -P -o '\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}'
  34. ifconfig eth0|grep Bcast| grep -P -o '(\d{1,3}.){3}\d{1,3}'
  35. ifconfig eth0|grep Bcast| grep -P -o '(\d+.){3}\d+'
  36. # egrep --color '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /etc/sysconfig/network-scripts/ifcfg-eth0
  37. IPADDR=10.1.1.1
  38. NETMASK=255.255.255.0
  39. GATEWAY=10.1.1.254
  40. # egrep --color '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}' /etc/sysconfig/network-scripts/ifcfg-eth0
  41. IPADDR=10.1.1.1
  42. NETMASK=255.255.255.0
  43. GATEWAY=10.1.1.254
  44. 14、找出文件中的ip地址并且打印替换成172.16.2.254
  45. grep -o -E '([0-9]{1,3}\.){3}[0-9]{1,3}' 1.txt |sed -n 's/192.168.0.\(254\)/172.16.2.\1/p'
  46. 15、找出文件中的ip地址
  47. grep -o -E '([0-9]{1,3}\.){3}[0-9]{1,3}' 1.txt
  48. 16、找出全部是数字的行
  49. grep -E '^[0-9]+$' test
  50. 17、找出邮箱地址
  51. grep -E '^[0-9]+@[a-z0-9]+\.[a-z]+$'
  52. grep --help:
  53. 匹配模式选择:
  54. Regexp selection and interpretation:
  55. -E, --extended-regexp 扩展正则
  56. -G, --basic-regexp 基本正则
  57. -P, --perl-regexp 调用perl的正则
  58. -e, --regexp=PATTERN use PATTERN for matching
  59. -f, --file=FILE obtain PATTERN from FILE
  60. -i, --ignore-case 忽略大小写
  61. -w, --word-regexp 匹配整个单词

七、课后作业

脚本搭建web服务

要求如下

  1. 用户输入web服务器的IP、域名以及数据根目录
  2. 如果用户不输入则一直提示输入,直到输入为止
  3. 当访问www.test.cc时可以访问到数据根目录里的首页文件“this is test page”

参考脚本:

  1. 参考:
  2. #!/bin/bash
  3. conf=/etc/httpd/conf/httpd.conf
  4. input_fun()
  5. {
  6. input_var=""
  7. output_var=$1
  8. while [ -z $input_var ]
  9. do
  10. read -p "$output_var" input_var
  11. done
  12. echo $input_var
  13. }
  14. ipaddr=$(input_fun "Input Host ip[192.168.0.1]:")
  15. web_host_name=$(input_fun "Input VirtualHostName [www.test.cc]:")
  16. root_dir=$(input_fun "Input host Documentroot dir:[/var/www/html]:")
  17. [ ! -d $root_dir ] && mkdir -p $root_dir
  18. chown apache.apache $root_dir && chmod 755 $root_dir
  19. echo this is $web_host_name > $root_dir/index.html
  20. echo "$ipaddr $web_host_name" >> /etc/hosts
  21. [ -f $conf ] && cat >> $conf <<end
  22. NameVirtualHost $ipaddr:80
  23. <VirtualHost $ipaddr:80>
  24. ServerAdmin webmaster@$web_host_name
  25. DocumentRoot $root_dir
  26. ServerName $web_host_name
  27. ErrorLog logs/$web_host_name-error_log
  28. CustomLog logs/$web_host_name-access_loh common
  29. </VirtualHost>
  30. end