Shell—正则表达式(grep命令、sed工具),


 

前言

正则表达式对于系统管理员来说是非常重要的,熟练运用正则表达式可使工作变得更加简单、方便。

一、正则表达式概述

正则表达式定义

正则表达式,又称正规表达式、常规表达式

使用字符串来描述、匹配一系列符合某个规则的字符串

简单来说,是一种匹配字符串的方法,通过一些特殊符号,实现快速查找、删除、替换某个特定字符串。

正则表达式组成

普通字符:大小写字母、数字、标点符号及一些其他符号

元字符:在正则表达式中具有特殊意义的专用字符

正则表达式的用途

正则表达式对于系统管理员来说是非常重要的,系统运行过程中会产生大量的信息,这些信息有些是非常重要的,有些则仅是告知的信息。身为系统管理员如果直接看这么多的信息数据,无法快速定位到重要的信息,如“用户账号登录失败”“服务启动失败”等信息。这时可以通过正则表达式快速提取“有问题”的信息。如此一来,可以将运维工作变得更加简单、方便。

正则表达式分类

基础正则表达式

扩展正则表达式

Linux中文本处理工具

支持基础正则表达式:grep;sed

支持扩展正则表达式:egrep;awk

基础正则表达式元字符

基础正则表达式是常用的正则表达式部分

除了普通字符外,常见到以下元字符

  1. ■ \  :转义字符,\!、 \n等     #让特殊意义的元字符作普通字符使用  
  2. ■ ^ :匹配字符串开始的位置  
  3. 例: ^a、 ^the、 ^#  
  4. ■ $ :匹配字符串结束的位置  
  5. 例: word$  
  6. ■  . :匹配除\n之外的任意的一个字符  
  7.  例: go.d、 g..d  
  8. ■  * :匹配前面子表达式0次或者多次  
  9.  例: goo*d、 go.*d  
  10. ■ [list] :匹配list列表中的一个字符  
  11.  例: go[ola]d 、[abc]、 [a-z]、 [a-z0-9]  
  12. ■ [^list] :匹配任意不在list列表中的一个字符  
  13.  例: [^a-z]、 [^0-9]、 [^A-Z0-9]  
  14. ■ \{n,m\} :匹配前面的子表达式n到m次,有\{n\}、 \{n,\}、\{n,m\}三种格式  
  15.  例: go\{2\}d、 go\{2,3\}d、 go\{2,\}d  
  16.  注意:“o{1,}” 等价于 “o+”  ;“o{0,}” 则等价于 “o*” 

二、grep 命令

2.1 grep的使用规则:

  •  -n:表示显示行号
  •  -i :表示不区分大小写
  •  -v:表示反向过滤
  •  [ ]:查找集合字符

2.2 用法示例

  1. grep -n 'the' test.txt     #文件检索出带‘the’的行并显示行号  
  2. grep -vn 'the' test.txt   #文件反向检索出不带‘the’的行并显示行号  
  3. grep -n 'sh[oi]rt' test.txt  #文件检索出带‘short’或‘shirt‘的行并显示行号  
  4. grep -n 'oo' test.txt   #文件检索出至少带连续oo的行并显示行号  
  5. grep -n 'o\{2\}' test.txt   #文件检索出至少带连续oo的行并显示行号  
  6. grep -n 'o\{2,\}' test.txt   #文件检索出至少带连续oo的行并显示行号  
  7. grep -n '[^w]oo' test.txt   #文件检索出连续oo前面不带w的行并显示行号  
  8. grep -n '^[^w]oo' test.txt  #文件检索出除w外,任意*oo开头的行并显示行号  
  9. grep -n ' [^a-z]oo ' test.txt  #文件检索出连续oo前面不是小写字母的行并显示行号  
  10. grep -n '[0-9]' test.txt    #文件检索出包含数字的行并显示行号  
  11. grep -n '[^0-9]' test.txt  #文件检索出不包含纯数字的行并显示行号,非纯数字也会匹配  
  12. grep -n '[^#]' test.txt   #文件检索出不包含#的行并显示行号  
  13. grep -n '^the' test.txt  #文件检索出以‘the’开头的行并显示行号  
  14. grep -n ‘^[a-z] ' test.txt   #文件检索出以小写字母开头的行并显示行号  
  15. grep -n ‘^[A-Z] ' test.txt   #文件检索出以大写字母开头的行并显示行号  
  16. grep -n '^[^a-zA-Z]' test.txt   #文件检索出不以字母开头的行并显示行号  
  17. grep -n '\.$' test.txt  #文件检索出以 . 号结尾的行并显示行号  
  18. grep -n '^$' test.txt   #文件检索出空行并显示行号  
  19. grep -n 'w..d' test.txt  #文件检索出带有w开头,d结尾,中间两个任意字符的行并显示行号  
  20. grep -n 'ooo*' test.txt  #文件检索出带有连续oo或两个0以上的行并显示行号  
  21. grep -n 'oo*' test.txt  #文件检索出带有o或一个0以上的行并显示行号  
  22. grep -n 'w.*d' test.txt   #文件检索出带有w开头,d结尾,中间任意字符也可中间什么也没有的行并显示行号  
  23. grep -n '[0-9][0-9]*' test .txt  #文件检索出带有数字的行并显示行号 

三、sed 工具

sed(StreamEDitor)

一个强大而简单的文本解析转换工具,可以读取文本,并根据指定的条件对文本内容进行编辑(删除、替换、添加、移动等),最后输出所有行或者仅输出处理的某些行。

3.1 sed 工具使用规则

sed的工作流程

主要包括读取、执行和显示三个过程

读取: sed从输入流(文件、管道、标准输入)中读取一-行内容并存储到临时的缓冲区中(又称模式空间,pattern space)

执行: 默认情况下,所有的sed命令都在模式空间中顺序地执行,除非指定了行的地址,否则sed命令将会在所有的行上依次执行。

显示: 发送修改后的内容到输出流。在发送数据后,模式空间将会被清空。在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完。

注意:默认情况下所有的sed命令都是在模式空间内执行的,因此输入的文件并不会发生任何变化,除非是用重定向存储输出。

sed命令常见用法

  1. sed [选项] ‘操作’ 参数  
  2. sed [选项] -f scriptfile 参数 

常见的sed命令选项

  •  -e script: 指定sed编辑命令
  •  -f scriptfile: 指定的文件中是sed编辑命令
  •  -h或–help: 显示帮助
  •  -n、–quiet或silent:表示仅显示处理后的结果。
  •  -i: 直接编辑文本文件

常见sed命令的操作

  •  a: 增加,在当前行下面增加一行指定内容。
  •  c: 替换,将选定行替换为指定内容。
  •  d: 删除,删除选定的行。
  •  i: 插入,在选定行上面插入一行指定内容。
  •  p: 打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以ASCII码输出。其通常与“-n”选项一起使用。
  •  s: 替换,替换指定字符。
  •  y: 字符转换。
  •  p:n #奇数行
  •  n:p #偶数行

3.2 用法示例

1、输出符合条件的文本(p表示正常输出)

nl test.txt | sed -n ‘p’ #输出test.txt内容,nl是显示行号和内容,为的是输出结果带上行号

  1. nl test.txt | sed -n '3p'   #输出test.txt内容第三行带行号  
  2. nl test.txt | sed -n '2,5p'   #输出test.txt内容二到五行带行号  
  3. nl test.txt | sed -n 'p:n'   #输出test.txt内容奇数行带行号,要先删除空格  
  4. nl test.txt | sed -n 'n:p'   #输出test.txt内容偶数行带行号,要先删除空格  
  5. nl test.txt | sed -n '1,5{p;n}'  #输出test.txt内容奇数行1~5行带行号  
  6. nl test.txt | sed -n '1,10{n;p}'  #输出test.txt内容偶数行1~10行带行号  
  7. nl test.txt l sed -n '10,${n; p}'  #输出test.txt内容10行到最后一行的偶数行带行号  
  8. sed -n '/the/p' test.txt     #输出test.txt带the的内容  
  9. grep -n 'the' test.txt   #文件检索出带‘the’的行并显示行号 
  10. nl test.txt | sed -n '4,/the/p'    #输出test.txt内容4行以后带‘the’的行带行号  
  11. sed -n '/the/=' test.txt   #输出带‘the’的行的行号  
  12. sed -n '/^PI/p' test.txt     #查找以‘PI’开头的行输出  
  13. sed -n '/[0-9]$/p' test.txt   #查找以数字结尾的行输出  
  14. grep 'wood' test.txt   #查找带‘wood’的行输出  
  15. sed -n '/\<wood\>/p' test.txt    #输出包含‘wood’的行,\< \>代表单词边界 

2、删除符合条件的文本 (d) #只删除输出流,不删除源文件

nl 命令用于计算文件的行数和显示内容

  1. nl test.txt | sed '3d'        #删除文本第三行  
  2. nl test.txt | sed '3,5d'        #删除文本第三到第五行  
  3. nl test.txt l sed -n '/cross/p'     #查找带‘cross’的行输出带行号  
  4. nl test.txt l sed  '/cross/d'     #删除带‘cross’的行  
  5. nl test.txt l sed  '/cross/!d'     #!取反,保留带‘cross’的行  
  6. sed '/^[a-z]/d' test.txt | nl  #删除以小写字母开头的行,结果显示行号  
  7. sed '/^[a-z]/d' test.txt     #删除以小写字母开头的行  
  8. sed -n '/\.$/d' test.txt   #删除以 . 号结尾的行  
  9. sed 'p' test.txt    #所有内容输出  
  10. sed '/^$/d' test. txt   #删除空行  
  11. sed '/.$/d' test.txt   #删除任意字符结尾的行,等于全删 

3、替换符合条件的文本

使用 sed 命令进行替换操作时需要用到 s (字符串替换);c (整行/整块替换);y (字符转换) 命令选项

  1. sed 's/the/THE/' test.txt    #将每行中的第一个the替换为THE  
  2. sed 's/1/L/2' test.txt    #将每行中的第2个1替换为L  
  3. sed 's/the/THE/g' test.txt     #将文件中的所有the替换为THE  
  4. sed 's/o//g' test.txt     #将文件中的所有o删除(替换为空串)  
  5. sed 's/^/#' test.txt      #在每行行首插入#号  
  6. sed '/the/s/^/#/' test.txt    #在包含the 的每行行首插入#号  
  7. sed 's/$/EOF/' test.txt    #在每行行尾插入字符串 EOF  
  8. sed '3,5s/the/THE/g' test.txt    #将第3~5 行中的所有the替换为 THE  
  9. sed '/the/s/o/0/g'test.txt    #将包含the的所有行中的o都替换为O 

4、迁移符合条件的文本

在使用sed 命令迁移符合条件的文本时,常用到以下参数:

  •  H:复制到剪贴板;
  •  g、G:将剪贴板中的数据覆盖/追加至指定行
  •  w :保存为文件
  •  r :读取指定文件
  •  a:追加指定内容。 
  1. sed '/the/{H; d};$G' test.txt     #将包含the 的行迁移至文件末尾,{;}用于多个操作  
  2. sed '1,5 {H; d};17G' test.txt   #将第1~5 行内容转移至第17行后  
  3. sed '/the/w out.file' test.txt    #将包含the 的行另存为文件 out.file  
  4. sed '/the/r /etc/hostname' test.txt   #将文件/etc/hostname 的内容添加到包含 the 的每行以后  
  5. sed '3aNew' test.txt   #在第3行后插入一个新行,内容为New  
  6. sed '/the/aNew' test.txt   #在包含the的每行后插入一个新行,内容为New  
  7. sed '3aNew1\nNew2' test.txt  #在第3行后插入多行内容,中间的\n表示换行  
  8. 注:\n和\r的区别:  
  9. \n:换行符  是另起一新行  
  10. \r :回车符  光标回到一旧行的开头; 

5、使用脚本编辑文件

使用sed脚本将多个编辑指令存放到文件中(每行一条编辑指令),通过“-f”选项来调用。

  1. [root@client2 ~]# vi opt.list    #建立一个文件  
  2. 5H       #文件内是sed的操作  
  3. 5d  
  4. 16G  
  5. [root@client2 ~]# sed -f opt.list test.txt      #对test.txt进行操作 

6、sed直接操作文件示例

编写一个脚本,用来调整vsftpd 服务配置,要求禁止匿名用户,但允许本地用户

  1. [root@server2 ~]# useradd dada  
  2. [root@server2 ~]# passwd dada  
  3. [root@server2 ~]# useradd xiaoxiao  
  4. [root@server2 ~]# passwd xiaoxiao  
  5. [root@server2 ~]# vi ftp.sh  
  6. #!/bin/bash  
  7. A=vsftpd  
  8. FTP=/etc/vsftpd/vsftpd.conf  
  9. yum -y install $A  
  10. sed -i -e '/local_enable/s/NO/YES/g' $FTP  
  11. sed -i -e '/write_enable/s/NO/YES/g' $FTP  
  12. sed -i -e 's/^#chroot_local_user=YES/chroot_local_user=YES/g' $FTP  
  13. sed -i  '$aallow_writeable_chroot=YES' $FTP  
  14. sed -i -e '/listen/s/NO/YES/g' $FTP  
  15. sed -i -e '/listen_ipv6/s/YES/NO/g' $FTP  
  16. systemctl start $A  
  17. netstat -anpt | grep $A  
  18. [root@server2 ~]# chmod +x ftp.sh  
  19. [root@server2 ~]# ./ftp.sh 

客户机上安装ftp进行访问

  1. [root@server1 ~]# yum -y install ftp  
  2. [root@server1 ~]# ftp 20.0.0.11  
  3. Name (20.0.0.11:root): dada  
  4. ftp> exit  
  5. [root@server1 ~]# ftp 20.0.0.11  
  6. Name (20.0.0.11:root): xiaoxiao  
  7. ftp> exit 

验证成功

相关内容