shell
grep 模糊搜索
sed 非交互式对文档进行修改
awk 精确搜索
sed高级应用
sed删除字符(如删行首,行尾单个字符)
- 案例1 删除文件中每行的第一个 和 最后一个字符
- sed ‘s/.//’ test
用 空 替换test每一行的第一个任意字符,
即删除每一行第一个字符 - sed ‘s/.$//’ test
用 空 替换test 每一行的 最后一个 任意字符,
即删除每一行最后一个字符- sed ‘/the/s/.$//’ test 删除包含the的一行的最后一个字符
- sed ‘s/.//’;‘s/.$//’ test
- 案例 2 删除所有数字 返回
- sed -i ‘s/[0-9]//g’ 文本
sed复制,粘贴
's/^(.)(.*)(.)$/\3\2\1/' a
^(.) 复制行首单个任意字符
\1 粘贴第一个保留()内容
(.*) .*通配符, 复制任意个符号
( )扩展正则的符号:
可以实现保留功能, 将括号内容复制
粘贴时, 需要用 \数字 如\1是粘贴第一个
- 案例3 将每行的第一个,与 倒数第一个替换
[root@localhost ~]# cat a
abc
xyz
[root@localhost ~]# sed -r 's/(a)(b)(c)/\1\2\3/' a //扩展
abc
xyz
[root@localhost ~]# sed -r 's/(a)(b)(c)/\3\2\1/' a //具体字符替换
cba
xyz
[root@localhost ~]# sed -r 's/(.)(.)(.)/\3\2\1/' a //任意单个字符替换
cba
zyx
[root@localhost ~]#
长字符头尾替换 返回
[root@localhost ~]# cat a
abc
xyz
fdafdafdafe12132
头324325尾
[root@localhost ~]# sed -r 's/^(.)(.*)(.)$/\3\2\1/' a
cba
zyx
2dafdafdafe1213f
尾324325头
[root@localhost ~]#
- 案例4 为文件中每个大写字母添加括号
- sed -r ‘s/([A-Z])/(\1)/g’
- -r 使用扩展正则
- ([A-Z]) 复制任意一个大写字母
- (\1) 粘贴第一个保留()符号的内容, 并加一个括号()
[root@localhost ~]# sed -r 's/([A-Z])/(\1)/g' sedtest.txt
(H)ello the (W)orld
ni hao ma (B)eijing
2212357982(V)3454328hj
req rew rew req eee
the the (G)old
[root@localhost ~]#
sed案例实战—搭建ftp实现匿名上传文件
-
ftp 配置文件 /etc/vsftpd/vsftpd.conf
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zujZ6G58-1594078631044)(408D24C738B042818FF445ACD6DFB788)]
anon_upload_enable=YES 匿名上传功能 -
实现匿名上传文件到服务器中可能影响的因素
- 配置文件
- 目录权限 ----共享文件需有rwx
- 防火墙
- Selinux 返回
xftp设置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QTsLCbGO-1594078631051)(4AC3BD88DFA74EBA884F8478C6FB33C3)]
[root@localhost opt]# vim anon_upload-ftp.sh
#!/bin/bash
yum -y install vsftpd #1 装ftp包
sed -i '/anon_up/s/#//' /etc/vsftpd/vsftpd.conf #2 改配置文件
systemctl restart vsftpd #3 起服务
systemctl enable vsftpd #开机自启
chmod 777 /var/ftp/pub #4 开放共享文件rwx权限
setenforce 0 #5 临时关闭selinux为pemissive
firewall-cmd --set-default-zone=trusted #6 设置防火墙为trusted
sed 其他指令
- a 行下方追加
- i 行上方追加
- c 替换整行 返回
[root@localhost ~]# sed 'a 666' a
23232
666
3fdafd
666
afdauh
666
[root@localhost ~]# sed '1a 666' a
23232
666
3fdafd
afdauh
[root@localhost ~]# sed '/ni/a 666' a
23232
3fdafd
afdauh
[root@localhost ~]# sed '/af/a 666' a //包含af的行,下一行插入666
23232
3fdafd
666
afdauh
666
[root@localhost ~]# sed 'i 666' a //所有行上方插入666
666
23232
666
3fdafd
666
afdauh
[root@localhost ~]# sed 'c 666' a //全替换
666
666
666
[root@localhost ~]# sed '1c 666' a //第一行替换
666
3fdafd
afdauh
[root@localhost ~]#
sed综合脚本
本案例要求编写脚本getupwd.sh,实现以下需求:返回
- 找到使用bash作登录Shell的本地用户
- 列出这些用户的shadow密码记录
- 按每行“用户名 --> 密码记录”保存到getupwd.log,如图-1所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NZz7yxS1-1594078631053)(AC05623608204CBC81D92B51EE6ACABA)] - sed -n ‘/bash$/s/:.*//’ /etc/passwd 全部屏蔽,不显示
- sed -n ‘/bash$/s/:.*//p’ /etc/passwd 只屏蔽默认输出
[root@localhost ~]# sed -n '/bash$/s/:.*//p' /etc/passwd
root
wanger
test01
//....省略
uuu
[root@localhost ~]#
[root@localhost opt]# vim getupwd.sh
#!/bin/bash
if [ ! -z /opt/getupwd.log ];then
rm -rf /opt/getupwd.log
fi
n=$(sed -n '/bash$/s/:.*//p' /etc/passwd) #获取用bash登录的用户名
for i in $n #循环匹配到的用户名
do
g=$(grep $i /etc/shadow) #逐个匹配对应密码行,命令赋值需加$()或``
df=${g#*:} #掐头,删第一个:之前字符
m=${df%%:*} #去尾,删第二个:之后的字符
echo "$i --> $m" >> /opt/getupwd.log
done
############# 运行脚本测试 ################
[root@localhost opt]# bash getupwd.sh
[root@localhost opt]# cat getupwd.log
root --> $6$VzRc/HqXVjvMXuEc$P7GwkeSCx16azYooUVC5AEJXV99fdrov3C3HhIzl4hwWYcpvfQuUR1pXwHc5FFYn4U..Vs3uwYIerDR7NV8ap1
1 --> $6$VzRc/HqXVjvMXuEc$P7GwkeSCx16azYooUVC5AEJXV99fdrov3C3HhIzl4hwWYcpvfQuUR1pXwHc5FFYn4U..Vs3uwYIerDR7NV8ap1
v --> $6$VzRc/HqXVjvMXuEc$P7GwkeSCx16azYooUVC5AEJXV99fdrov3C3HhIzl4hwWYcpvfQuUR1pXwHc5FFYn4U..Vs3uwYIerDR7NV8ap1
t --> $6$VzRc/HqXVjvMXuEc$P7GwkeSCx16azYooUVC5AEJXV99fdrov3C3HhIzl4hwWYcpvfQuUR1pXwHc5FFYn4U..Vs3uwYIerDR7NV8ap1
r --> $6$VzRc/HqXVjvMXuEc$P7GwkeSCx16azYooUVC5AEJXV99fdrov3C3HhIzl4hwWYcpvfQuUR1pXwHc5FFYn4U..Vs3uwYIerDR7NV8ap1
e --> $6$VzRc/HqXVjvMXuEc$P7GwkeSCx16azYooUVC5AEJXV99fdrov3C3HhIzl4hwWYcpvfQuUR1pXwHc5FFYn4U..Vs3uwYIerDR7NV8ap1
ussss1 --> !!
ussss2 --> !!
[root@localhost opt]# vim getupwd.sh
awk
grep 模糊搜索 #匹配整行
sed 非交互式对文档进行修改 #匹配整行,并可增删改
awk 精确搜索 #匹配文档各字符串, 行列划分.匹配到具体字符串单元
awk基本用法
逐行搜索文档
前置指令 | awk 选项 条件 指令
awk 选项 条件 指令 被处理文档
- 选项 -F 定义分隔符
- 指令 print
- 内置变量
‘{print $1,$0}’ 先输出第一列, 再输出所有列
$0 $1 $2 $3 ...
所有列 第1列 第2列 第3列
NR 行号 所有行的行号
NF 列号 所有行都有几列
[root@localhost opt]# awk '{print}' test //输出所有行的内容
Hello tHe woRLd
ni Hao Ma beijing
[root@localhost opt]# awk 'print' test //大括号为{}固定格式, 不能省
awk: cmd. line:1: print
awk: cmd. line:1: ^ syntax error
[root@localhost opt]# awk '{print $0}' test //输出所有行的第1列
Hello tHe woRLd
ni Hao Ma beijing
[root@localhost opt]# awk '{print $1,$2,$0}' test //输出所有行的第1列, 第2列 ,和所有所有列
Hello tHe Hello tHe woRLd
ni Hao ni Hao Ma beijing
[root@localhost opt]# awk '{print NR}' test //输出所有行的行号
1
2
[root@localhost opt]# awk '{print NF}' test //输出所有行都有几列
3
4
[root@localhost opt]#
- 找到某行的某列
‘/字符串/{print $n}’
[root@localhost opt]# awk -F: '/root/{print $3}' test //找到含有"root"行的第3列 ,,以: 为分割符,划分列
0
[root@localhost opt]# awk -F: '/root/{print $6,$7}' test
/root /bin/bash
[root@localhost opt]#
-F 分隔符
- 使用: 为分隔符 返回
[root@localhost opt]# awk '{print $1}' test //不加分隔符默认为一列
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
//以:为分隔符, 输出所有行的第1列
[root@localhost opt]# awk -F: '{print $1}' test
root
bin
daemon
adm
lp
//以: 为分隔符, 输出所有行的第1列,和第3列
[root@localhost opt]# awk -F: '{print $1,$3}' test
root 0
bin 1
daemon 2
adm 3
lp 4
- 以/ 为分隔符
[root@localhost opt]# awk -F/ '/root/{print $1}' test
root:x:0:0:root:
- -F[./] 以. 或 / 为分隔符
- ./ 点和斜杠中间为一个空列
- “常量” print输出的内容,如果加了双引号, 会被认为是常量
- 变量加常量, 让输出更丰富
[root@localhost opt]# awk -F: '/root/{print $1,"的解释器是",$7}' test
root 的解释器是 /bin/bash
案例
1 提取网卡流量信息
- RX 接收流量
- TX 发送流量 返回
[root@localhost opt]# ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.4.6 netmask 255.255.255.0 broadcast 192.168.4.255
inet6 fe80::3998:fa41:774e:b510 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:09:56:e7 txqueuelen 1000 (Ethernet)
RX packets 8935 bytes 763669 (745.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5781 bytes 813465 (794.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@localhost opt]# ifconfig ens33 | awk '/RX p/{print "ens33网卡 的发送流量."$5"字节"}''
ens33网卡 的发送流量是770247字节
[root@localhost opt]# ifconfig ens33 | awk '/TX p/{print "ens33网卡 的发送流量."$5"字节"}''
ens33网卡 的发送流量是825603字节
[root@localhost opt]# ifconfig ens33 | awk '/TX p/{print "ens33网卡 的发送流量是",$5,"字节"}'
ens33网卡 的发送流量是 842217 字节
[root@localhost opt]#
2 查看根分区剩余容量
df -h | awk '/\/$/{print "根分区的剩余容量为",$4}'
\/$ 反斜杠转义/, 常量后跟, 显示为一个空格
###########################################
[root@localhost opt]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-root 17G 1.3G 16G 8% /
devtmpfs 476M 0 476M 0% /dev
tmpfs 488M 0 488M 0% /dev/shm
tmpfs 488M 7.7M 480M 2% /run
tmpfs 488M 0 488M 0% /sys/fs/cgroup
/dev/sda1 1014M 130M 885M 13% /boot
tmpfs 98M 0 98M 0% /run/user/0
/dev/sr0 8.8G 8.8G 0 100% /mydvd
[root@localhost opt]# df -h | awk '/\/$/{print "根分区的剩余容量为",$4}'
根分区的剩余容量为 16G
[root@localhost opt]#
3 日志数据提取
- /var/log/secure 系统的安全日志
- 时刻被系统锁定, 不要用vim 打开
- 可使用tail 查看
awk ‘/Failed password/{print $11}’ /var/log/secure 返回
[root@localhost opt]# tail -5 /var/log/secure
Jul 7 00:27:37 localhost sshd[2240]: pam_succeed_if(sshd:auth): requirement "uid >= 1000" not met by user "root"
Jul 7 00:27:39 localhost sshd[2240]: Failed password for root from 192.168.4.1 port 55470 ssh2
Jul 7 00:27:40 localhost sshd[2240]: error: Received disconnect from 192.168.4.1 port 55470:0: [preauth]
Jul 7 00:27:40 localhost sshd[2240]: Disconnected from 192.168.4.1 port 55470 [preauth]
Jul 7 00:27:40 localhost sshd[2240]: PAM 1 more authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.4.1 user=root
[root@localhost opt]# awk '/Failed password/{print NR}' /var/log/secure //匹配字符对应的所有行号
169
172
[root@localhost opt]# awk '/Failed password/{print NF}' /var/log/secure //所在行的第几列
14
14
[root@localhost opt]# awk '/Failed password/{print $11}' /var/log/secure
192.168.4.1
192.168.4.1
[root@localhost opt]#
4 awk处理时机
- { } 逐行操作, 执行文件多少行输出多少 次 返回
- BEGIN{ } 逐行任务之前的, 执行 1 次
- END{ } 逐行任务之后, 执行1次。
- END{print NR} 输出最后一行行号,可代表有多少行
- tab 制表符 在一定程度上对文档进行排版
- \t 制作表头,自动对齐
#BEGIN{}写到后面, 也会在前面显示
[root@localhost opt]# awk 'BEGIN{print "begin"}{print "middle"}BEGIN{print "end"}' test
begin
end
middle
middle
middle
middle
middle
[root@localhost opt]# awk 'BEGIN{print "begin"}{print "middle"}END{print "end"}' test
begin
middle
middle
middle
middle
middle
end
[root@localhost opt]#
- begin 1次 逐行5次 end 1次 , 并逐行显示行号 返回
// begin 1次 逐行5次 end 1次 , 并逐行显示行号
[root@localhost opt]# awk 'BEGIN{print "begin"}{print "middle"}END{print "end"}{print NR}' test
begin
middle
1
middle
2
middle
3
middle
4
middle
5
end
[root@localhost opt]# awk 'BEGIN{print "begin"}{print "middle"}END{print "end"}{print NF}' test //列号为 1
begin
middle
1
middle
1
middle
1
middle
1
middle
1
end
[root@localhost opt]#
格式化输出/etc/passwd文件
返回
要求: 格式化输出passwd文件内容时,要求第一行为列表标题,中间打印用户的名称、UID、家目录信息,最后一行提示一共已处理文本的总行数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nrcC7WUf-1594078631057)(C1E5526F40A74ED0A9A089733C7088CC)]
- 常量没有加双引号, 系统会当变量处理, 出现报错
[root@localhost opt]# awk -F: 'BEGIN{print "User\tUID\tHome"}{print $1"\t"$3"\t"$6}END{print "Total",NR,"lines."}' /etc/passwd
User UID Home
root 0 /root
bin 1 /bin
daemon 2 /sbin
adm 3 /var/adm
lp 4 /var/spool/lpd
sync 5 /sbin
//...省略
ussss1 1005 /home/ussss1
ussss2 1006 /home/ussss2
Total 28 lines.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uXWp0bU0-1594078631059)(B3B149E924ED4D388EF43BFACF6AF801)]
返回