理论+实验 详解Shell编程之正则表达式与文本处理器

目录

  • 一 正则表达式
    • 1.1 基础正则表达式
    • 1.2 扩展正则表达式
  • 二 文件处理器
    • 2.1 sed
    • 2.2 awk
    • 2.3 sort
    • 2.4 uniq
    • 2.5 tr

一 正则表达式

理论+实验 详解Shell编程之正则表达式与文本处理器_第1张图片
理论+实验 详解Shell编程之正则表达式与文本处理器_第2张图片

1.1 基础正则表达式

理论+实验 详解Shell编程之正则表达式与文本处理器_第3张图片

[root@localhost ~]# vi 123.txt    //编辑一个测试文本
hort and fat.
He was wearing a blue polo shirt with black pants. The home of Football on BBC Sport online.
the tongue is boneless but it breaks bones.12! google is the best tools for search keyword.
The year ahead will test our political establishment to the limit.
PI=3.141592653589793238462643383249901429
a wood cross!
Actions speak louder than words


#woood # #woooooood # AxyzxyzxyzxyzC
I bet this place is really spooky late at night! Misfortunes never come alone/single.

I shouldn't have lett so tast.

[root@localhost ~]# grep -n 'the' 123.txt   //刷选文件中包含the的行
3:the tongue is boneless but it breaks bones.12! google is the best tools for search keyword.
4:The year ahead will test our political establishment to the limit.

[root@localhost ~]# grep -vn 'the' 123.txt    //刷选文件中不包含the的行
1:hort and fat.
2:He was wearing a blue polo shirt with black pants. The home of Football on BBC Sport online.
5:PI=3.141592653589793238462643383249901429
6:a wood cross!
7:Actions speak louder than words
8:
9:
10:#woood # #woooooood # AxyzxyzxyzxyzC
11:I bet this place is really spooky late at night! Misfortunes never come alone/single.
12:
13:I shouldn't have lett so tast.

[root@localhost ~]# grep -in 'the' 123.txt   //刷选文件中包含the的行,不区分大小写
2:He was wearing a blue polo shirt with black pants. The home of Football on BBC Sport online.
3:the tongue is boneless but it breaks bones.12! google is the best tools for search keyword.
4:The year ahead will test our political establishment to the limit.

[root@localhost ~]# grep -n 'sh[io]rt' 123.txt   //刷选出文件中包含shirt或short字符串的行
2:He was wearing a blue polo shirt with black pants. The home of Football on BBC Sport online.

[root@localhost ~]# grep -n 'oo' 123.txt   //筛选出字符串中包含两个oo的行
2:He was wearing a blue polo shirt with black pants. The home of Football on BBC Sport online.
3:the tongue is boneless but it breaks bones.12! google is the best tools for search keyword.
6:a wood cross!
10:#woood # #woooooood # AxyzxyzxyzxyzC
11:I bet this place is really spooky late at night! Misfortunes never come alone/single.

[root@localhost ~]# grep -n '[^w]oo' 123.txt   //筛选出以w开头后面有两个o的字符串的行
2:He was wearing a blue polo shirt with black pants. The home of Football on BBC Sport online.
3:the tongue is boneless but it breaks bones.12! google is the best tools for search keyword.
10:#woood # #woooooood # AxyzxyzxyzxyzC
11:I bet this place is really spooky late at night! Misfortunes never come alone/single.

[root@localhost ~]# grep -n 'ooo' 123.txt   //筛选出包含三个o的字符串的行
10:#woood # #woooooood # AxyzxyzxyzxyzC

[root@localhost ~]# grep -n 'ooo*' 123.txt   //筛选出有两个o以上字符串的行
2:He was wearing a blue polo shirt with black pants. The home of Football on BBC Sport online.
3:the tongue is boneless but it breaks bones.12! google is the best tools for search keyword.
6:a wood cross!
10:#woood # #woooooood # AxyzxyzxyzxyzC
11:I bet this place is really spooky late at night! Misfortunes never come alone/single.

[root@localhost ~]# grep -n 'woo*d' 123.txt   //筛选出wd中间至少有一个o的字符串的行
6:a wood cross!
10:#woood # #woooooood # AxyzxyzxyzxyzC

[root@localhost ~]# grep -n '[0-9][0-9]*' 123.txt   //筛选出包含0-9中数字的字符串的行
3:the tongue is boneless but it breaks bones.12! google is the best tools for search keyword.
5:PI=3.141592653589793238462643383249901429

[root@localhost ~]# grep -n 'o\{2\}' 123.txt   //筛选出有连续两个o的字符串的行
2:He was wearing a blue polo shirt with black pants. The home of Football on BBC Sport online.
3:the tongue is boneless but it breaks bones.12! google is the best tools for search keyword.
6:a wood cross!
10:#woood # #woooooood # AxyzxyzxyzxyzC
11:I bet this place is really spooky late at night! Misfortunes never come alone/single.

[root@localhost ~]# grep -n 'wo\{2,5\}d' 123.txt   //筛选出wd中间有2-5个o的字符串的行
6:a wood cross!
10:#woood # #woooooood # AxyzxyzxyzxyzC

[root@localhost ~]# grep -n 'wo\{2,\}d' 123.txt   //筛选出wd中间至少有两个及两个以上o的字符串的行
6:a wood cross!
10:#woood # #woooooood # AxyzxyzxyzxyzC

1.2 扩展正则表达式

理论+实验 详解Shell编程之正则表达式与文本处理器_第4张图片

[root@localhost ~]# egrep -n 'wo+d' 123.txt   //查询文件中wd中间有一个或以上的字符串的行
6:a wood cross!
10:#woood # #woooooood # AxyzxyzxyzxyzC

[root@localhost ~]# egrep -n 'bes?t' 123.txt   //查询文件中包含bet或best字符的行
3:the tongue is boneless but it breaks bones.12! google is the best tools for search keyword.
11:I bet this place is really spooky late at night! Misfortunes never come alone/single.

[root@localhost ~]# egrep -n 'of|is|on' 123.txt   //查询文件中包含of或者is或者on字符的行
2:He was wearing a blue polo shirt with black pants. The home of Football on BBC Sport online.
3:the tongue is boneless but it breaks bones.12! google is the best tools for search keyword.
4:The year ahead will test our political establishment to the limit.
7:Actions speak louder than words
11:I bet this place is really spooky late at night! Misfortunes never come alone/single.

[root@localhost ~]# egrep -n 't(a|e)st' 123.txt   //查询文件中包含tast或者test字符的行
4:The year ahead will test our political establishment to the limit.
13:I shouldn't have lett so tast.

[root@localhost ~]# egrep -n 'A(xyz)+C' 123.txt   //查询文件中以A开头C结尾中间有一个以上xyz字符的行
10:#woood # #woooooood # AxyzxyzxyzxyzC

二 文件处理器

2.1 sed

■ 文本处理工完成自动化处理任务具,读取文本内容,根据指定的条件进行处理,如删除,替换,添加等
■ 可在无交互的情况下实现相当复杂的文本处理操作
■ 被广泛应用于Shell脚本,以完成自动化处理任务
■ sed依赖于正则表达式
■ 工作原理
在这里插入图片描述
■ sed命令格式
sed -e ‘编辑指令’ 文件1 文件2 …
sed -n -e ‘编辑指令’ 文件1 文件2 …
sed -i -e ‘编辑指令’ 文件1 文件2 …
■ 常用选项
-e 指定要执行的命令,只有一个编辑命令时可省略
-n 只输出处理后的行,读入时不显示
-i 直接编辑文件,而不输出结果
-f 用指定的脚本文件来处理输入的文本文件
■ 编辑命令格式
[地址[,地址2]]操作[参数]
◆地址:可数字,正则表达式,$,没有地址代表是所有行
◆操作:可以是a,c,d,p,s,r,w,i,s,y等
◆参数:一般有g,代表只要符合条件的全部进行处理
(1)打印内容

[root@localhost ~]# vi 1.txt  //创建测试文件
11
22
33
44
55
[root@localhost ~]# sed -n -e 'p' 1.txt //显示打印所有内容
11
22
33
44
55
[root@localhost ~]# sed -n -e '=' 1.txt   //打印行号
1
2
3
4
5
[root@localhost ~]# sed -n -e 'l' 1.txt   //打印所有内容,包括非打印字符,以ASCII码输出
11$
22$
33$
44$
55$
[root@localhost ~]# sed -n -e '=;p' 1.txt   //打印行号以及所有内容
1
11
2
22
3
33
4
44
5
55
[root@localhost ~]# sed -n -e '=' -e 'p' 1.txt 
1
11
2
22
3
33
4
44
5
55

(2)使用地址
sed编辑器有2种寻址方式

  1. 以数字形式表示行区间
  2. 用文本模式来过滤出行
[root@localhost ~]# sed -n '1p' 1.txt   //打印第一行内容
11
[root@localhost ~]# sed -n '$p' 1.txt   //打印最后一行内容
55
[root@localhost ~]# sed -n '1,3p' 1.txt  //打印1到3行内容
11 
22
33
[root@localhost ~]# sed -n '3,$p' 1.txt   //打印第3行到尾行的内容
33
44
55
[root@localhost ~]# sed -n '1,+3p' 1.txt   //打印第1行以及下面3行的内容
11
22
33
44
[root@localhost ~]# sed '4q' 1.txt   //打印前4行内容后退出
11
22
33
44
[root@localhost ~]# sed -n 'p;n' 1.txt   //打印奇数行
11
33
55
[root@localhost ~]# sed -n 'n;p' 1.txt   //打印偶数行
22
44
[root@localhost ~]# sed -n '2,/44/p' 1.txt   //打印第2行到44字符的所有行内容
22
33
44
[root@localhost ~]# sed -n '/44/=' 1.txt   //打印44字符所在的行数
4
[root@localhost ~]# sed -nr '/44{1,}/p' 1.txt   //打印4后面有1个4字符的内容,-r表示支持正则表达式
44

(3)删除行

[root@localhost ~]# sed 'd' 1.txt   //删除所有
[root@localhost ~]# sed '3d' 1.txt   //删除第三行内容
11
22
44
55
[root@localhost ~]# sed '2,4d' 1.txt   //删除第2行至第4行的内容
11
55
[root@localhost ~]# sed '$d' 1.txt   //删除最后一行的内容
11
22
33
44
[root@localhost ~]# sed '/55/!d' 1.txt   //除了55都删除。"!"表示取反操作
55
[root@localhost ~]# sed '/1/,/3/d' 1.txt   //从第一个位置打开行删除功能,到第二个位置关闭行删除功能
44
55

(4)替换标记

  1. 数字:表明新字符串将替换第几处匹配的地方
  2. g:表明新字符串将会替换所有匹配的地方
  3. p:打印与替换命令匹配的行,与-n一起使用
  4. w 文件:将替换的结果写到文件中
[root@localhost ~]# sed -n 's/root/admin/p' /etc/passwd  //将第一段的root替换为admin
admin:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/admin:/sbin/nologin
[root@localhost ~]# sed -n 's/root/admin/2p' /etc/passwd  //将第二段的root替换为admin
root:x:0:0:admin:/root:/bin/bash
[root@localhost ~]# sed -n 's/root/admin/gp' /etc/passwd  //将文本中所有的root替换为admin
admin:x:0:0:admin:/admin:/bin/bash
operator:x:11:0:operator:/admin:/sbin/nologin
[root@localhost ~]# sed '1,10 s/^/#/' /etc/passwd  //将文本前10行开头添加#为开头
#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
#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:/sbin/nologin
#operator:x:11:0:operator:/root:/sbin/nologin
......
[root@localhost ~]# sed '1,10w out.txt' /etc/passwd  //将前10行内容覆盖到out.txt中
[root@localhost ~]# ls
123.txt          Desktop               out.txt    text11.sh  text3.sh  text8.sh
[root@localhost ~]# cat out.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
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:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

(5)插入

[root@localhost ~]# sed '/11/c AAA' 1.txt   //将11字符替换为AAA
AAA
22
33
44
55
[root@localhost ~]# sed '/11/ y/11/AA/' 1.txt   //将11转换为AA
AA
22
33
44
55
[root@localhost ~]# sed '$a AAA' 1.txt   //在尾行下一行添加AAA字符
11
22
33
44
55
AAA
[root@localhost ~]# sed '1i AAA' 1.txt   //在第一行上面添加一行AAA
AAA
11
22
33
44
55
[root@localhost ~]# sed '/root/{H;d};$G' /etc/passwd  //将包含root的行剪切到末尾,H表示复制到剪切板,G表示粘贴到指定行后
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
......

root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

2.2 awk

■常见用法
通常情况下 awk 所使用的命令格式如下所示,其中,单引号加上大括号“{}”用于设置对数据进行的处理动作。awk 可以直接处理目标文件,也可以通过“-f”读取脚本对目标文件进行处理。

awk 选项 '模式或条件 {编辑指令}' 文件 1 文件 2 … //过滤并输出文件中符合条件的内容
awk   -f   脚本文件 文件 1 文件 2 …	//从脚本中调用编辑指令,过滤并输出内容

■awk工作原理图
理论+实验 详解Shell编程之正则表达式与文本处理器_第5张图片
■awk包含的特殊内建变量
FS:指定每行文本的字段分隔符,默认为空格或制表位
NF:当前处理的行的字段个数
NR:当前处理的行的行号(序数)
$0:当前处理的行的整行内容
$n:当前处理行的第 n 个字段(第 n 列)
FILENAME:被处理的文件名
RS:数据记录分隔,默认为\n,即每行为一条记录
■用法示例
(1)按行输出文本

awk '{print}' test.txt	//输出所有内容,等同于 cat test.txt
awk '{print $0}' test.txt	//输出所有内容,等同于 cat test.txt
awk 'NR==1,NR==3{print}' test.txt	//输出第 1~3 行内容
awk '(NR>=1)&&(NR<=3){print}' test.txt	//输出第 1~3 行内容
awk 'NR==1||NR==3{print}' test.txt	//输出第 1 行、第 3 行内容
awk '(NR%2)==1{print}' test.txt	//输出所有奇数行的内容
awk '(NR%2)==0{print}' test.txt	//输出所有偶数行的内容
awk '/^root/{print}' /etc/passwd	//输出以root 开头的行
awk '/nologin$/{print}' /etc/passwd	//输出以 nologin 结尾的行
awk 'BEGIN {x=0};/\/bin\/bash$/{x++};END {print x}' /etc/passwd
//统计以/bin/bash 结尾的行数,等同于 grep -c "/bin/bash$" /etc/passwd
awk 'BEGIN{RS=""};END{print NR}' /etc/squid/squid.conf
//统计以空行分隔的文本段落数

(2)按字段输出文本

awk '{print $3}' test.txt	//输出每行中(以空格或制表位分隔)的第 3 个字段
awk '{print $1,$3}' test.txt	//输出每行中的第 1、3 个字段
awk -F ":" '$2==""{print}' /etc/shadow //输出密码为空的用户的shadow 记录
awk 'BEGIN {FS=":"}; $2==""{print}' /etc/shadow
//输出密码为空的用户的shadow 记录
awk -F ":" '$7~"/bash"{print $1}' /etc/passwd
//输出以冒号分隔且第 7 个字段中包含/bash 的行的第 1 个字段
awk '($1~"nfs")&&(NF==8){print $1,$2}' /etc/services
//输出包含 8 个字段且第 1 个字段中包含 nfs 的行的第 1、2 个字段
awk -F ":" '($7!="/bin/bash")&&($7!="/sbin/nologin"){print}' /etc/passwd
//输出第 7 个字段既不为/bin/bash 也不为/sbin/nologin 的所有行

(3)通过管道,双引号调用Shell命令

awk -F: '/bash$/{print | "wc -l"}' /etc/passwd
//调用wc -l 命令统计使用 bash 的用户个数,等同于 grep -c "bash$" /etc/passwd
awk 'BEGIN {while ("w" | getline) n++ ; {print n-2}}'
//调用w 命令,并用来统计在线用户数
awk 'BEGIN { "hostname" | getline ; print $0}'
//调用hostname,并输出当前的主机名

2.3 sort

■用法
sort [选项] 参数
■常用选项
-f:忽略大小写;
-b:忽略每行前面的空格;
-M:按照月份进行排序;
-n:按照数字进行排序;
-r:反向排序;
-u:等同于 uniq,表示相同的数据仅显示一行;
-t:指定分隔符,默认使用[Tab]键分隔;
-o <输出文件>:将排序后的结果转存至指定文件;
-k:指定排序区域。
■用法示例

[root@localhost ~]# sort /etc/passwd  //将/etc/passwd文件中的账号进行排序
abrt:x:173:173::/etc/abrt:/sbin/nologin 
adm:x:3:4:adm:/var/adm:/sbin/nologin 
apache:x:48:48:Apache:/var/www:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin bin:x:1:1:bin:/bin:/sbin/nologin
......


[root@localhost ~]# sort -t ':' -rk 3 /etc/passwd  //将/etc/passwd文件中第三列进行反向排序
nobody:x:99:99:Nobody:/:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin 
dbus:x:81:81:System message bus:/:/sbin/nologin mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin
halt:x:7:0:halt:/sbin:/sbin/halt
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin 
haldaemon:x:68:68:HAL daemon:/:/sbin/nologin
......

[root@localhost ~]# sort -t ':' -k 3 /etc/passwd -o user.txt  //将/etc/passwd文件中第三列进行排序,并将输出内容保存至user.txt文件中
[root@localhost ~]# cat user.txt 
root:x:0:0:root:/root:/bin/bash 
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin 
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin 
bin:x:1:1:bin:/bin:/sbin/nologin 
games:x:12:100:games:/usr/games:/sbin/nologin gopher:x:13:30:gopher:/var/gopher:/sbin/nologin 
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin abrt:x:173:173::/etc/abrt:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin 
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
......

2.4 uniq

■用法
uniq [选项] 参数
■常用选项
-c:进行计数
-d:仅显示重复行
-u:仅显示出现一次的行
■示例

[root@localhost ~]# cat testfile
Linux 10
Linux 20
Linux 30
Linux 30
Linux 30
CentOS 6.5
CentOS 6.5
CentOS 6.5
CentOS 7.3
CentOS 7.3
CentOS 7.3
[root@localhost ~]# uniq testfile  //删除testfile文件中的重复行
Linux 10
Linux 20
Linux 30
CentOS 6.5
CentOS 7.3
[root@localhost ~]# uniq -c testfile  //删除testfile文件中的重复行,并在行首显示该行重复出现的次数
1 Linux 10
1 Linux 20
3 Linux 30
3 CentOS 6.5
3 CentOS 7.3
[root@localhost ~]# uniq -d testfile  //查找testfile文件中的重复行
Linux 30
CentOS 6.5
CentOS 7.3

2.5 tr

■用法
tr [选项] [参数]
■常用选项
-c:取代所有不属于第一字符集的字符;
-d:删除所有属于第一字符集的字符;
-s:把连续重复的字符以单独一个字符表示;
-t:先删除第一字符集较第二字符集多出的字符。
■示例

[root@localhost ~]# echo "KGC" | tr 'A-Z' 'a-z'  //将输入字符由大写转换为小写
kgc
[root@localhost ~]# echo "thissss is	a text linnnnnnne." | tr -s 'sn'  //压缩输入中重复的字符
this is a text line.
[root@localhost ~]# echo 'hello world' | tr -d 'od'  //删除字符串中某些字符
hell wrl

你可能感兴趣的:(实验,理论)