shell编程之正则表达式与文本处理器

目录

  • 一、正则表达式
    • 一、基础正则表达式
    • 二、扩展正则表达式
  • 二、Linux文本处理工具
    • 一、三剑客之grep
    • 二、三剑客之sed
    • 一、格式
    • 二、常用选项及匹配模式
    • 三、三剑客之awk
      • 一、选项及变量
      • 二、格式
      • 三、简单实例

一、正则表达式

一、定义
1、正则表达式,又称正规表达式、常规表达式
2、使用字符串来描述、匹配一系列符合某 个规则的字符串
二、正则表达式组成
1、普通字符:大小写字母、数字、标点符号及一些其他符号
2、元字符:在正则表达式中具有特殊意义的专用字符

一、基础正则表达式

元字符 含义
\ 转义字符,\!、 \n等
^ 匹配字符串开始的位置
\< 匹配以……开头的行
\> 匹配以……结尾的行
\<……\> 匹配含有某个单词的行
$ 匹配字符串结束的位置
^$ 空行
. 匹配除\n之外的任意的一个字符
* 匹配前面子表达式0次或者多次
.* 表示任意长度的字符
[list] 匹配list列表中的一个字符
[^list] 匹配任意不在list列表中的一一个字符
^[list] 匹配list列表中一个或多个字符开头
^[^list] 匹配不包含list列表中一个或多个字符开头
{n,m)} 匹配前面的子表达式n到m次,有{n)}、 {n,}、{n,m}三种格式

二、扩展正则表达式

扩展元字符 含义
+ 匹配前面子表达式1次以上
? 匹配前面子表达式0次或者1次
() 将括号中的字符串作为一个整体
| 以或的方式匹配字条串
{n} 前面一个字符出现n次
{n,} 前面一个字符至少出现n次
{n,m} 前面一个字符至少出现n次,最多出现m次

二、Linux文本处理工具

一、三剑客之grep

1、grep命令是文本搜索命令,它可以正则表达式搜索文本,也可从一个文件中的内容作为搜索关键字。
2、grep的工作方式是这样的,它在一个或多个文件中搜索字符串模板。如果模板包括空格,则必须被引用,模板后的所有字符串被看作文件名。搜索的结果被送到标准输出,不影响原文件内容。
3、在文件中查找并显示包含指定字符串的行

代码选项 含义
grep “root” test 在test中查找含有root的行
grep “^root” test 在test中查找以root开头的行
grep “root$” test 在test中查找以root结尾的行
grep “^$” test 在 test中查找空行,一般和-v使用
grep -i 不区分大小写
grep -v 过滤/不匹配
grep -E 可用扩展元字符(使用
grep -o 只把匹配到字符的行打印出来
grep -n 显示行号
grep -w 精准匹配单词
grep -c 只显示匹配了多少行

二、三剑客之sed

1、文本处理工具,读取文本内容,根据指定的条件进行处理,如删除、替换、添加等
2、可在无交互的情况下实现相当复杂的文本处理操作
3、sed依赖于正则表达式
4、匹配模式中不识别先后,按照文件内容逐行匹配显示

一、格式

[root@localhost ~]# sed 选项 匹配模式 文件名
[root@localhost ~]# sed '' tt.txt #没有模式匹配,也要加单引号

shell编程之正则表达式与文本处理器_第1张图片

二、常用选项及匹配模式

选项
-e:执行多个命令时使用,执行一个时可以省略
-n:只输出处理后的行,读入时不显示
-r:表示使用扩展正则表达式
-i:直接编辑文件,不输出结果
-f:用指定的脚本来处理输入的文本文件
匹配模式
a:追加 ,向匹配行后面插入内容
c:更改,更改匹配行整行的内容
i:插入,向匹配行前插入内容/忽略大小写(写在后面)
d:删除,删除匹配的内容
s:替换 ,替换掉匹配的内容
p:打印 ,打印出匹配的内容,通常与-n选项和用
=:用来打印被匹配的行的行号
n:读取下一行,遇到n时会自动跳入下一行
r,w:读和写编辑命令,r用于将其他文件内容读入本文件,w用于将匹配内容写入到其他文件
g:全局操作
q:退出
[root@localhost ~]# cat /etc/passwd | head -10 > p.txt#复制/etc/passwd前十行内容到p.txt
-n实例
[root@localhost ~]# cat -n p.txt | sed -n '1,3p'#打印131	root:x:0:0:root:/root:/bin/bash
     2	bin:x:1:1:bin:/bin:/sbin/nologin
     3	daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@localhost ~]# cat -n p.txt | sed -n '1~2p'#从1行开始,间隔两行打印
     1	root:x:0:0:root:/root:/bin/bash
     3	daemon:x:2:2:daemon:/sbin:/sbin/nologin
     5	lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     7	shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
     9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
[root@localhost ~]# cat -n p.txt | sed -n '1,+2p'#打印从第一行开始往后打印21	root:x:0:0:root:/root:/bin/bash
     2	bin:x:1:1:bin:/bin:/sbin/nologin
     3	daemon:x:2:2:daemon:/sbin:/sbin/nologin
-r实例
[root@localhost ~]# sed -nr '/^root|nologin$/p' p.txt#打印以root开头或以nologin结尾的行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
-e实例
[root@localhost ~]# sed -ne '/^root/p' -e '/nologin$/p' p.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
-f实例
[root@localhost ~]# vim sed.sh
#!/bin/sed -f
#可以分行写,也可以将命令写在一行但需要;隔开
s/root/ROOT/g
s/\/sbin\/nologin/xxx/g
1d
[root@localhost ~]# sed -f sed.sh p.txt#用sed.sh脚本执行p.txt文件
bin:x:1:1:bin:/bin:xxx
daemon:x:2:2:daemon:/sbin:xxx
adm:x:3:4:adm:/var/adm:xxx
lp:x:4:7:lp:/var/spool/lpd:xxx
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:xxx
operator:x:11:0:operator:/ROOT:xxx
替换:分隔符号可改
[root@localhost ~]#  sed -n 's#/sbin/nologin#xxx#p' p.txt
bin:x:1:1:bin:/bin:xxx
daemon:x:2:2:daemon:/sbin:xxx
adm:x:3:4:adm:/var/adm:xxx
lp:x:4:7:lp:/var/spool/lpd:xxx
mail:x:8:12:mail:/var/spool/mail:xxx
operator:x:11:0:operator:/root:xxx
[root@localhost ~]#  sed -n 's@/sbin/nologin@xxx@p' p.txt
bin:x:1:1:bin:/bin:xxx
daemon:x:2:2:daemon:/sbin:xxx
adm:x:3:4:adm:/var/adm:xxx
lp:x:4:7:lp:/var/spool/lpd:xxx
mail:x:8:12:mail:/var/spool/mail:xxx
operator:x:11:0:operator:/root:xxx

三、三剑客之awk

awk相对于grep和sed,可以对文本内容的列处理,但不会像sed那样直接修改文件。
awk可以编程,可以使用if语句,for循环,函数,属组等。

一、选项及变量

awk选项
-F:指定分隔符,多个分隔符用[]
例:awk -F[:/] '{print}' /etc/passwd
-f:指定脚本
-V:查看awk的版本号
-v:参数传递,定义和引用变量 ,可以把外部变量引入到内部

awk内置变量
NF:显示多少列
NR:显示行号
$0:打印整行
$1:第一列,默认以空格或Tab建作为分隔
$n:第n列
FS:列分割符,指定每行文本的字段分隔符,默认为空格或制表位。与"-F"作用相同
OFS:表示输出时以什么分隔,默认以空格分隔,ofs可以定义以什么分隔
RS:对行的分隔 ,以什么换行(文件里有的才能作为分隔)
ORS:对行的分隔,指定两行之间的连接(可以以任何作为连接)
BEGIN:一般用来做初始化操作,仅在读取数据记录之前执行一次,可以用来运算或引用变量
END:一般用来汇总操作,仅在读取数据记录之后执行一次
例:[root@localhost ~]# awk 'END{print $0}' /etc/passwd #打印最后一行内容
a:x:1008:1008::/home/a:/bin/bash
[root@localhost ~]# awk 'END{print NR}' /etc/passwd #处理完内容,显示行号
53

二、格式

awk 选项 ‘{命令部分}’ 文件名
if语句格式
单分支:if(){}
双分支:if(){}else{}
多分支:if(){}else if(){}else{}

三、简单实例

1、列出系统中用bash环境的用户

[root@localhost ~]# awk -F: '/bash$/{print NR,$1}' /etc/passwd

shell编程之正则表达式与文本处理器_第2张图片
2、查看/etc/passwd这个文件,要求筛选出用户,uid和家目录,以及统计出一个共有多少个用户

[root@localhost ~]# awk -F: 'BEGIN{print "User\tUID\tHome\t"}$3<5{print $1"\t"$3"\t"$6}END{print "Tota "NR" linrs"}' /etc/passwd

在这里插入图片描述
3、写一个脚本输出所有系统中的用户和他加密后的密码

#!/bin/bash
user=`awk -F: '/bash$/{print $1}' /etc/passwd`
for i in $user
do
    grep $i /etc/shadow | awk -F: '$2!~/!/{print $1"的密码是"$2}'
done

在这里插入图片描述

你可能感兴趣的:(Shell)