shell用法sed和awk


grep 模糊搜索                   
sed  非交互式对文档进行修改
awk  精确搜索

sed高级应用

sed删除字符(如删行首,行尾单个字符)
  • 案例1 删除文件中每行的第一个 和 最后一个字符
  1. sed ‘s/.//’ test

    用 空 替换test每一行的第一个任意字符,
    删除每一行第一个字符
  2. sed ‘s/.$//’ test

    用 空 替换test 每一行的 最后一个 任意字符,

    删除每一行最后一个字符
    • sed ‘/the/s/.$//’ test 删除包含the的一行的最后一个字符
  3. 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 匿名上传功能

  • 实现匿名上传文件到服务器中可能影响的因素

  1. 配置文件
  2. 目录权限 ----共享文件需有rwx
  3. 防火墙
  4. 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 其他指令

  1. a    行下方追加
  2. i     行上方追加
  3. 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 分隔符
  1. 使用: 为分隔符 返回
[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
  1. 以/ 为分隔符
[root@localhost opt]# awk -F/ '/root/{print $1}' test
root:x:0:0:root:
  1. -F[./] 以. 或 / 为分隔符
    • ./ 点和斜杠中间为一个空列
  2. “常量” 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)]
返回

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值