1、grep
全局搜索正则表达式
[root@desktop mnt]# grep root passwd #过滤出passwd中含root的行
[root@desktop mnt]# grep ^root passwd #^ 表示以root开头行
[root@desktop mnt]# grep root$ passwd #$ 表示以root结尾行
[root@desktop mnt]# grep -i root passwd #-i 忽略大小写
[root@desktop mnt]# grep -E "root|ROOT" passwd #-E 扩展正则表达式,相当于egrep,|表示或
[root@desktop mnt]# grep -v "root|ROOT" passwd #-v 反向过滤
[root@desktop mnt]# grep -E "r...\>" test #不做拓展搜索,精确匹配关键字
root
rootroot
[root@desktop mnt]# grep -E "\<r...\>" test
root
[root@desktop mnt]# grep r...t test #.表示位数,精确指定
rooot
rooat
[root@desktop mnt]# grep r..t test
root
rootroot
[root@desktop mnt]# grep -E "ro*t" test ##*表示字符ro出现0到任意次
root
rt
rooot
rot
rootroot
rooooot
grep中字符的匹配次数设定
- 字符出现0-任意次 ? 字符出现0-1次
- 字符出现1-任意次 {m,n} 字符出现最少出现m次,最多出现n次 {0,n} 字符出现0-n次 {m,} 字符出现至少m次 .* 关键字之间匹配任意字符 [root@desktop mnt]# grep -E “ro?t” test
#?表示字符ro出现0到1次 rt rot
[root@desktop mnt]# grep "ro\{1,\}t" test #\表示转义,加-E后不用写\
root
rooot
rot
rootroot
rooooot
[root@desktop mnt]# grep -E "ro+t" test ##"ro+t"表示字符ro出现1到任意次
root
rooot
rot
rootroot
rooooot
[root@desktop mnt]# grep -E "ro{,2}t" test #"ro{,2}t"表示字符ro出现0到2次
root
rt
rot
rootroot
[root@desktop mnt]# grep -E "(root)?" test #"(root)?"表示字符root出现0到1次
root
rt
rooot
rot
rootroot
rooat
rooooot
[root@desktop mnt]# grep -E "r.*t" test #关键字之间匹配任意字符
root
rt
rooot
rot
rootroot
rooat
rooooot
练习:
要求:
shell脚本:显示系统中可以登陆的用户
#!/bin/bash
SHELL=$(echo `grep -v nologin /etc/shells`|sed 's/ /|/g')
grep -E "$SHELL" /etc/passwd |cut -d : -f 1
2:diff
比较两个文件或目录的不同:A文件在第三行末尾比B文件第三行末尾多一个空格
diff A B ##比较A文件和B文件的不同
diff -b A B ## -b 不检查空格字符的不同
-B:不检查空白行
A文件比B文件多了两行空格
-c:显示全部内容,并标出不同
diff -c A B
A文件和B文件的时间戳不同,并且A文件比B文件在末尾多了两行空格
-i:不检查大小写的不同
-q仅显示有无差异,不显示详细信息
-r:比较子目录中的文件:
[root@localhost shell]# ll dir
total 4
-rw-r--r--. 1 root root 16 Aug 20 21:02 A
[root@localhost shell]# ll dir1
total 4
-rw-r--r--. 1 root root 16 Aug 20 21:03 B
[root@localhost shell]# diff -r dir/A dir1/B
2c2
< WORLD
---
> world
-u:用合并的方式显示文件的不同:
[root@localhost shell]# diff -u A B
--- A 2019-08-20 21:00:05.573033206 +0800
+++ B 2019-08-20 20:48:13.892026477 +0800
@@ -1,3 +1,3 @@
hello
-WORLD
+world
123
3:cut:多用于字符截取:
cut -d 指定分隔符
cut -f 1,7|1-7 指定截取的列
cut -c 1,4|1-4 指定截取的字符位置
截取主机ip:
root@localhost shell]# ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.80.0 netmask 255.255.255.0 broadcast 192.168.80.255
inet6 fe80::20c:29ff:fe2e:df7c prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:2e:df:7c txqueuelen 1000 (Ethernet)
RX packets 8744 bytes 1622879 (1.5 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2416 bytes 394688 (385.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@localhost shell]#
[root@localhost shell]# ifconfig ens33 | head -n 2 | tail -n 1
inet 192.168.80.0 netmask 255.255.255.0 broadcast 192.168.80.255
[root@localhost shell]# ifconfig ens33 | head -n 2 | tail -n 1 | cut -d " " -f 10
192.168.80.0
截取passwd中第三行的sbin:/sbin
cut -d "/" -f 2,3 以/为分隔符,截取第二第三列
4:sort:常用语字符的排序:
vim shuzi:
sort -n shuz
-n参数:纯数字正序排序
sort -r shuzi
-r参数:纯数字倒叙排序
sort -un shuzi
-u:纯数字去掉重复数字后正序排序:
sort -nu shuzi -o file
-o:输出到指定文件file
sort -nu -t " " -k 2 shuzi -o file
-t:指定分隔符
-k:指定要排序的列
对文件shuzi的第二列进行去重正向排序,并指定分隔符为空格,然后输出到文件file中
5:&&和||
&& 用来执行条件成立后执行的命令
|| 用来执行条件不成立后执行的命令
编写脚本文件,分别执行,ping本机和其他主机ip,可以看到的到不同的结果:
6:sed
行编辑器
(1)p显示模式
[root@desktop mnt]# sed -n '/^UUID/p' fstab #显示以UUID开头的行
[root@desktop mnt]# sed -n '/0$/p' fstab #显示以0结尾的行
[root@desktop mnt]# sed -n '/^UUID/!p' fstab #不显示以UUID开头的行
[root@desktop mnt]# cat -n fstab|sed -n '/2,6/!p' fstab #显示2-6行
[root@desktop mnt]# cat -n fstab|sed -n -e '2p' -e '6p'#显示2和6行,多个条件用-e连接
(2)d删除模式(不用加-n)
[root@desktop mnt]# sed '/^$/d' fstab #删除空行
[root@desktop mnt]# sed '2d;6d' fstab #删除2和6行
[root@desktop mnt]# sed -n '/^UUID/d' fstab #删除以UUID开头的行
[root@desktop mnt]# sed -n '/0$/d' fstab #删除以0结尾的行
(3)a添加模式
[root@desktop mnt]# cat test
hello
[root@desktop mnt]# sed '/hello/aworld' test #给test文件hello后加world,添加到下一行
hello
world
[root@desktop mnt]# sed 's/hello/hello world/g' test #行后添加相当于修改本行
hello world
[root@desktop mnt]# sed '/hello/aworld\nwestos' test #插入多行,\n表示换行
hello
world
westos
(4)i插入模式
(5)c替换模式
[root@desktop mnt]#cat westos
hello
[root@desktop mnt]#sed '/hello/chello world' westos
hello world
[root@desktop mnt]#sed '/hello/cwestos\nworld' westos
westos
world
(6)w写入模式
处理一行写一行,效率高
[root@desktop mnt]# sed -n ‘/hello/wfile’ westos #将westos中的hello写入file文件,file不存在时会自动创建
[root@desktop mnt]# cat file
hello
[root@desktop mnt]# sed -n ‘/hello/p’ -i file #作用同上,file不存在时会报错
[root@desktop mnt]# cat file
hello
(7)其他用法
[root@desktop mnt]# sed ‘=’ fstab #给fstab每一行添加行号
N 每一行添加换行符
G 每一行后添加空行
显示文件匹配的内容,及其所在的行
(8)s替换
[root@desktop mnt]# sed 's/nologin/###/g' passwd #全文替换nologin为###
[root@desktop mnt]# sed '3,5s/nologin/###/g' passwd #3-5行的nologin替换为###
[root@desktop mnt]# sed '/adm/,/sync/s/sbin/@@@@@@/g' passwd #从adm到sync的所有sbin替换为@@@@@@
[root@desktop mnt]# sed -e '/adm/,/sync/s/sbin/@@@@@@/g;s/x/HHHHH@/g' passwd #替换从adm到sync的sbin,替换全文x
[root@desktop mnt]# vim file #编写一个替换规则的文件file
/adm/,/sync/s/sbin/@@@@@@/g
s/x/HHHHH/g
[root@desktop mnt]# sed -f file passwd #-f指定file的规则区替换passwd
[root@desktop mnt]# sed -f file -i passwd #指定file的规则替换passwd,同时输出到passwd更改其内容
7:wk报告生成器
[root@desktop mnt]# awk '{print NR}' passwd #打印passwd行号
[root@desktop mnt]# awk '{print NF}' passwd #打印passwd列号
[root@desktop mnt]# awk -F ":" 'BEGIN{print "NAME"}{print $1}END{print "END"}' passwd #打印passwd第一列,打印前先打印NAME,打印后再打印END
[root@desktop mnt]# awk '/nologin$/{print}' passwd #打印以nologin结尾的行
[root@desktop mnt]# awk -F ":" '/bash$/{print $1}' passwd #打印以bash结尾的行的第一列
[root@desktop mnt]# awk -F ":" 'BEGIN{N=0}/bash$/{N++}END{print N}' passwd #显示以bash结尾的行的数目
[root@desktop mnt]# awk 'BEGIN{N=0}//{N++}END{print N}' passwd #显示passwd文件的行数
[root@desktop mnt]# awk '/^[a-d]/{print}' passwd #打印passwd以a-d开头的行
[root@desktop mnt]# awk '/^[^a-d]/{print}' passwd #打印除a-d开头以外的行
[root@desktop mnt]# awk '/^a|nologin$/{print}' passwd #打印开头为a结尾为nologin的行
[root@desktop mnt]# awk '/^a/&&/nologin$/{print}' passwd #打印开头为a结尾为nologin的行
[root@desktop mnt]#ifconfig eth0 | awk '/inet\>/{print $2}' 显示本机ip
172.25.254.142
[root@desktop mnt]# awk 'BEGIN{n=0}{n++}END{print n}' /etc/passwd 显示文件passwd有多少行
26
8:test:可以用来比较字符的值:
命名两个变量,使用test命令进行验证:
test "$A" == "$B" 等同 [ "$A" == "$B" ] :比较A是否和B相等
[ "$A" != "$B" ] :比较A和B是否不等:
[root@localhost shell]# [ "$A" -eq "$B" ] && echo yes ||echo no A和B是否相等
no
[root@localhost shell]# [ "$A" -ne "$B" ] && echo yes ||echo no A不等于B
yes
[root@localhost shell]# [ "$A" -le "$B" ] && echo yes ||echo no A小于等于B
yes
[root@localhost shell]# [ "$A" -lt "$B" ] && echo yes ||echo no A小于B
yes
[root@localhost shell]# [ "$A" -gt "$B" ] && echo yes ||echo no A大于B
no
[root@localhost shell]# [ "$A" -ge "$B" ] && echo yes ||echo no A大于等于B
[ -z "$A" ]:判断字符串的长度是否为空
[ -n "$A" ]:判断字符串的长度是否为非空