shell脚本三剑客(grep sed awk ) 保姆级教程

目录

一.正则表达式

二,扩展正则

三,sed高级用法

sed配置实例1

sed配置实例2 

四,awk 搜索

awk流程控制


一.正则表达式

^匹配行首
$匹配行尾
  [ ]      集合,匹配集合中任意单个字符
[^]对集合取反
.匹配任意单个字符
*匹配前一个字符的任意次数(不允许单独使用)
\{n,m\}匹配前一个字符n到m次       
\{n\}匹配前一个字符n次
\{n,\}匹配前一个字符n次及以上
\{\}保留

1.使用   ^

[root@one ~]# grep ^root txt   //找txt文件 以root开头的行
root:x:0:0:root:/root:/bin/bash
 

2.使用$

[root@one ~]# grep bash$ txt   //找txt文件 以bash结尾的行
root:x:0:0:root:/root:/bin/bash

推导出    grep ^& txt              //匹配空行

[root@one ~]# grep -v root txt   //显示没有root的行

3.使用[]

[root@one etc]# grep [rot] ~/txt   //找到集合类的任意字符
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/n
ologin

[root@one etc]# grep bas[fghj] ~/txt //找到bas已fghj结尾的行

[root@one etc]# grep [^rot] ~/txt  //找不是rot的字母的所有字母

4.使用.

[root@one ~]# grep ba. txt    //找到ro后面以任意字符结尾的字符集
root:x:0:0:root:/root:/bin/
bash
 

5.使用*    匹配前一个字母的任意字符

ot@one ~]# grep ro* txt 
root:x:0:0:root:r/root:/bin/bash

ot@one ~]# grep bo*i txt

 root:x:0:0:root:/root:/bin/bash

[root@one ~]# grep ".*" txt      //匹配任意字符  需要加引号
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

                                                //空行

6.使用\{n,m\}  匹配字符n到m次

             \{n\} 匹配字符n次

             \{n,\}匹配字符n次以上

 [root@one ~]# grep "o\{2,5\}" txt  // 匹配字母0   2-5次的
root:x:0:0:root:/root:/bin/bash

[root@one ~]# grep "o\{2\}" txt    //匹配o 2次的
root:x:0:0:root:/root:/bin/bash

[root@one ~]# grep "o\{1,\}" txt    //匹配o 1次以上的 
root:x:0:0:root:/root:/bin/bash

二,扩展正则

+最少匹配一次       
最多匹配一次
{n,m}匹配n到m次
()组合为整体,保留        
|或者
\b单词边界

1.使用+ ? {n,m}

[root@one ~]# egrep  "ro+t"  txt    //匹配o最少一次
root:x:0:0:root:/root:/bin/bash

[root@one ~]# egrep  "ro?t" txt  //匹配o最多一次
root:x:0:0:root:/root:/bin/bash

[root@one ~]# egrep "ro{1,3}" txt //匹配o 1到3次
root:x:0:0:root:/root:/bin/bash

2.使用 |  \b

[root@one ~]# egrep "r|o|t" txt   //分别匹配r o t的字符
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

[root@one ~]# egrep "\bbin\b" txt //找出bin前后边界的字符
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

三,sed高级用法

sed 流式编辑器,可以非交互修改文本,逐行操作

一,使用 前置命令 | sed 选项(定址符)指令

二,sed  |  选项(定址符)文本

选项                                                   指令

-n 屏蔽默认输出                                           p输出指定内容

-r支持扩展正则                                           

-i写入文件             

1.p的用法                                             

[root@one ~]# sed -n '2p ' txt   //输出txt文件的第二行   -n是屏蔽默认输出
bin:x:1:1:bin:/bin:/sbin/nologin


[root@one ~]# df | sed -n '1,+3p'   //输出第一行和后面的三行
文件系统                   1K-块    已用     可用 已用% 挂载点
devtmpfs                  485380       0   485380    0% /dev
tmpfs                     497848       0   497848    0% /dev/shm  
tmpfs                     497848    7888   489960    2% /run


[root@one ~]# df | sed -n '/^tmpfs/p'  //输出tmpfs开头的行
tmpfs                     497848       0   497848    0% /dev/shm
tmpfs                     497848    7888   489960    2% /run
tmpfs                     497848       0   497848    0% /sys/fs/cgroup
tmpfs                      99572       0    99572    0% /run/user/0


[root@one ~]# df | sed  -n '$='   //显示df指令内容的行号
10

2.d的用法

[root@one ~]# df | sed '1d'   //删除第一行
devtmpfs                  485380       0   485380    0% /dev
tmpfs                     497848       0   497848    0% /dev/shm
tmpfs                     497848    7888   489960    2% /run
tmpfs                     497848       0   497848    0% /sys/fs/cgroup
/dev/mapper/centos-root 38094656 2445032 35649624    7% /
/dev/sda1                2086912  141236  1945676    7% /boot
/dev/mapper/vg1-lv1      3994560    8024  3787556    1% /lvm
/dev/sdb1               20510288   45080 19400300    1% /date
tmpfs                      99572       0    99572    0% /run/user/0

[root@one ~]# df | sed  '1~2d'  //删除奇数行 从第一行开始 隔两行删除
devtmpfs                  485380       0   485380    0% /dev
tmpfs                     497848    7888   489960    2% /run
/dev/mapper/centos-root 38094656 2445032 35649624    7% /
/dev/mapper/vg1-lv1      3994560    8024  3787556    1% /lvm
tmpfs                      99572       0    99572    0% /run/user/0
 正则需要//  和p的用法一致

sed  -i ‘/^ro/d’ txt   //删除已ro开头文件 并写入文件

3.s替换的用法

sed  's/old/new/'

[root@one ~]# cat txt 
2022 2023 2021
2022 2022 2025
2022 2022 2021

[root@one ~]# sed 's/2022/good/' txt   //将2022替换成good
good 2023 2021
good 2022 2025
good 2022 2021

[root@one ~]# sed 's/2022/good/g' txt  //将每一行的2022 换成good 
good 2023 2021
good good2025
good good 2021

[root@one ~]# sed 's/2022/good/3' txt  //将每一行第三个2022换成good
2022 2023 2021
2022 good 2025
2022 good 2021

sed配置实例1

1. 将sbin/nologin替换成sbin/login

[root@one ~]# cat 1txt 
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
 

[root@one ~]# sed 's@sbin/nologin@sbin/login@' 1txt      //  将 '/ / / '可以替换任意特殊字符
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/login
daemon:x:2:2:daemon:/sbin:/sbin/login
adm:x:3:4:adm:/var/adm:/sbin/login
lp:x:4:7:lp:/var/spool/lpd:/sbin/login
 

sed配置实例2 

[root@one ~]# cat txt 
aaaa 67bb CCC
xxxx vvvy 45a

1.删除每一行的第二个和最后一个

[root@one ~]# sed 's/.$//;s/.//2' txt
aaa 67bb CC
xxx vvvy 45a

2.去除文件中的数字
[root@one ~]# sed 's/[0-9]//g' txt
aaaa bb CCC
xxxx vvvy aa

3.首尾互相调换

[root@one ~]# sed -r 's/^(.)(.*)(.)$/\3\2\1/' txt
Caaa 67bb CCa
axxx vvvy 45ax

[root@one ~]# sed -r 's/([A-Z])/\[1]/' txt
aaa 67bb [C]CC
xxxx vvvy 45aa

sed配置实例3

实现vstpd服务包配置启动全过程,开启上传功能

#!bin/bash
yum - y install vsftpd $> /dev/null
sed -i 's/^#anon_up/anon_up/' /etc/vsftpd/vsftpd.conf
systemctl enable vsftpd --now
chmod o+w /var/ftp/pub

a 行后追加  i行前添加  c替换行

[root@master ~]# sed '10a 999' txt   //在第十行的后面追加加999
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
999
 

[root@master ~]# sed '/oper/i 999' txt   //在第oper的前面追加加999
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

999
operator:x:11:0:operator:/root:/sbin/nologin
 

[root@master ~]# sed '/^bin/c 100' txt  //以bin开头的行换成100
root:x:0:0:root:/root:/bin/bash
100
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

思考题 :如何使用sed和字符串判yum仓库的好坏


[root@master ~]# yum repolist | sed -n 's/^repolist: //p' | sed 's/,//' ;a=`yum repolist | sed -n 's/^repolist: //p' | sed 's/,//'`; [ $a  -gt 0 ] ; echo $?
28471
1
输出为0  可用源是大于0 域名仓库是好的

四,awk 搜索

主要用法

1.前置命令 | awk [选择] '[条件]{指令}'

[root@master ~]# awk '{print}' txt    //输出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
 

[root@master ~]# awk -F: '{print $1}' txt //F定义:为分隔符  &1为第一行
 root
bin
daemon
adm
lp

[root@master ~]# awk -F[:/] '{print $7}' txt  //以: /为分隔符
root
sbin
sbin
var
root

NR 行  NR 列
[root@master ~]# awk -F[:/] '{print "列数:"NF "   行数:" NR}' txt
列数:10   行数:1
列数:10   行数:2
列数:10   行数:3
列数:12   行数:4
列数:10   行数:5
 

awk配置实列1

查看网卡流量

[root@one ~]# ifconfig ens33 | awk '/RX pa|TX pa/{print $6"MB" }' | sed 's/(//'
189.4MB
154.6MB

逐行任务

2.awk  [选项] 'BEGIN {指令} {指令}END{指令}'  文件

 [root@one /]# cat /etc/passwd > txt && cat txt | head -5 |  awk -F[:] 'BEGIN{print "user\tuid\thome";x=0 }{x++;print $1"\t" $4"\t" $6"\t"}END{print "一共"x"行" }' 
user            uid    home
root             0    /root    
bin              1    /bin    
daemon      2    /sbin    
adm            4    /var/adm    
lp                7    /var/spool/lpd    
一共5行

//输出一个特定的表格    \t为tab会自动空行

用awk输出etc文件 不是nologin结尾的用户和解释器

[root@master ~]# awk -F: '$7!~/nologin$/{print $1,$7}' /etc/passwd
root /bin/bash
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt

 

用数值/字符串比比较设置条件

[root@master ~]# awk 'NR==5{print}' /etc/passwd  //查看密码文件的第五行
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

查看电脑有多少普通用户

awk '$3>=1000{print}' /etc/passwd | wc -l
0

使用逻辑符号 && ||

[root@master ~]# awk -F: '$3>100 && $3<200{print}' /etc/passwd
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
//第三列小于200 大于100的行

awk综合hsih

1.找出bash解释器登陆的shell用户

2.列出用户的shadow密码

3.按照每行 用户名 密码记录保存到ttx文件

#!bin/bash
ua=`awk -F: '/bash$/{print $1}' /etc/passwd`
#awk-F: '^/$a/{print $2}' /etc/shadow
for i in $ua
do
grep $i /etc/shadow |  awk -F: '{print $1" --> "$2}'
#     pass1=$(grep $i /etc/shadow)
#     pass2=${pass1#*:}      ##  #删除到:前面的字符  从左往右删除
#     pass=${pass2%%:*}     ##  %%去尾到:所有的 从右往左删除
#    echo "$i --> $pass"
done
~                

awk流程控制

[root@master ~]# awk 'BEGIN{a[0]=1;a[1]=2;for(i in a){print a[i]}}'
1
2
// 循环的是 a[0]的下表 而不是a的值

[root@one ~]# awk '{a[$1]++}END{for(i in a){print i,a[i]}}' txt
aaa 3
ccc 2
bbb 1
ddd 1
[root@one ~]# cat txt
aaa
aaa
bbb
ccc
aaa
ddd
ccc

//i为下标  后面的值为出现的次数
 

项目实战:

1.找出集群用户投递数量

[root@one ~]# cat txt
Job id            Name             User              Time Use S Queue
----------------  ---------------- ----------------  -------- - -----
131335.master     CAP-2022-031-BZ* guxuanang         00:06:22 R normal          
131336.master     CAP-2022-031-BZ* xukai             00:08:29 R normal          
131337.master     CAP-2022-031-BZ* guxuanang         00:05:03 R normal          
131363.master     CAP-2022-031-BZ* xukai                    0 H normal          
131364.master     CAP-2022-031-BZ* guxuanang                0 H normal          
131365.master     CAP-2022-031-BZ* lw                       0 H normal    

解题思路 将user提取出到文件txt2中

#!bin/bash
awk -F* 'NR>2 {print $2}' txt > txt1
awk '{print $1}' txt1 > txt2
awk 'BEGIN{print "用户\t任务数量"}{a[$1]++}END{for(i in a){print i"\t"a[i]}}' txt2

用户    任务数量
guxuanang    3
xukai    2
lw    1
 

2.密码输出三次发出警告

[root@one ~]# awk '/Failed/{a[$11]++}END{for(i in a){print i,a[i]}}' /var/log/secure
192.168.220.128 5
[root@one ~]# cat /var/log/secure | grep Failed
Aug 30 12:43:15 one sshd[2187]: Failed password for root from 192.168.220.128 port 43186 ssh2
Aug 30 12:43:17 one sshd[2187]: Failed password for root from 192.168.220.128 port 43186 ssh2
Aug 30 12:43:20 one sshd[2187]: Failed password for root from 192.168.220.128 port 43186 ssh2
Aug 31 15:12:15 one sshd[2374]: Failed password for root from 192.168.220.128 port 51212 ssh2
Aug 31 15:12:19 one sshd[2374]: Failed password for root from 192.168.220.128 port 51212 ssh2
 

#!bin/bash
a=`awk '/Failed/{a[$11]++}END{for(i in a){print i","a[i]}}' /var/log/secure`
for i in $a
do
  a1=${i#*,}    ##//接触出现的次数
  a2=${i%%,*}   ##//截取ip地址
  [ $a1 -gt 3 ]  && echo "$a2多次访问失败"
done

                                                       恭喜小伙伴顺利毕业

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值