22 grep、sed、awk三剑客初探

grep

用于过滤的命令

参数 作用
-i(常用) 搜索时,忽略大小写
-c(常用) 统计过滤成功的行数
-l 只列出符合匹配的文件名,不列出具体的匹配行
-n(常用) 列出所有的匹配行,显示行号
-h 查询多文件时不显示文件名
-s 不显示不存在、没有匹配文本的错误信息
-v 显示不包含匹配文本的所有行(取反)
-w(常用) 匹配整词
-x 匹配整行
-r 递归搜索
-q(常用) 禁止输出任何结果,已退出状态表示搜索是否成功
-b 打印匹配行距文件头部的偏移量,以字节为单位
-o 与-b结合使用,打印匹配的词据文件头部的偏移量,以字节为单位
-A 2 显示的时候加上后两行
-B 2 显示的时候加上前两行
-C 2 显示的时候增加前后两行
#语法
grep [选项] [正则] [文件]

#案例
[root@tencent_cloud test]# grep -rl "nginx" /etc/nginx/
/etc/nginx/koi-utf
/etc/nginx/nginx.conf
/etc/nginx/win-utf
/etc/nginx/fastcgi_params
#可以通过关键字查找相关的配置文件,当然也可以用rpm -qc nginx

正则表达式用法

符号 作用
^ 匹配从头开始对(中括号外)(中括号内是取反的意思)
$ 匹配从尾开始对
. 匹配任意一个字符
* 左边的字符出现0次或无穷次
.* 匹配所有的,默认是匹配到最远的
.*? 匹配所有的,改为非贪婪匹配,需要指定-P
[ ] 匹配指定范围的任意一个字符
+ 左边的字符出现1次或无穷次(egrep / grep -E才好用)

案例

^
[root@tencent_cloud ~]# grep -n "^root" tests 	#取第一个是root
1:root:x:0:0:root:/root:/bin/bash

$
[root@tencent_cloud ~]# grep -n "bash$" tests	#取结尾是bash的
1:root:x:0:0:root:/root:/bin/bash
26:lighthouse:x:1000:1000::/home/lighthouse:/bin/bash
28:mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
29:baimo:x:1001:1001::/home/baimo:/bin/bash

.
[root@tencent_cloud test]# cat a.txt
abc
a+c
a-c
a1c
aaaaaaaaaaaaaaaac
bbbbbbbbc
cccc
dddd
[root@tencent_cloud test]# grep -n "a.c" a.txt 
1:abc
2:a+c
3:a-c
4:a1c
5:aaaaaaaaaaaaaaaac

*
[root@tencent_cloud test]# cat a.txt 
a
ab
abbcccc
abbbbbbbbbbbbbbbbccc
bbbbbbbbbbbbb
aaaaaaaaaaaaaaaab

[root@tencent_cloud test]# grep "ab*" a.txt 
a
ab
abbcccc
abbbbbbbbbbbbbbbbccc
aaaaaaaaaaaaaaaab
#他这个匹配规则是,a是必须要有的,如果后面有多个a就一起拿走,b可有可无,有就都拿走,直到不是b为止

.*
[root@tencent_cloud test]# cat a.txt 
a123123213c3123123c
ac
a=-*(0c
cccccca123123c
[root@tencent_cloud test]# grep "a.*c" a.txt 	#贪婪匹配,从a开始到整行c结尾
a123123213c3123123c
ac
a=-*(0c
cccccca123123c

.*?
[root@tencent_cloud test]# cat a.txt 
<a href="http://www.baidu.com">我是百度</a><a href="http://www.sina.com.cn">新浪</a>
1111
2222
3333
[root@tencent_cloud test]# grep -Po '".*?"' a.txt 	#这里一定要指定-P,使用?的时候
"http://www.baidu.com"
"http://www.sina.com.cn"

[]
[root@tencent_cloud test]# cat >a.txt<<EOF
> abc
> aBc
> a1c
> a2c
> EOF
[root@tencent_cloud test]# grep 'a[a-z]c' a.txt 
abc
[root@tencent_cloud test]# grep 'a[A-Z]c' a.txt 
aBc
[root@tencent_cloud test]# grep 'a[a-zA-Z]c' a.txt 
abc
aBc
[root@tencent_cloud test]# grep 'a[0-9]c' a.txt 
a1c
a2c
#注意:[]内的减号代表的是范围的意思,如果要匹配-符号的话需要将-放在左右两侧
[root@www1 ~]# cat i.txt 
a+c
a-c
a*c
a/c
a1c
a2c
[root@www1 ~]# grep 'a[+-*/]c' i.txt 	#报错
grep: Invalid range end
[root@www1 ~]# grep 'a[+\-*/]c' i.txt 	#报错
grep: Invalid range end
[root@www1 ~]# grep 'a[+*/-]c' i.txt 	#OK
a+c
a-c
a*c
a/c
#注意:!在[]就是符号的意思,没有取反的意思,括号内取反需要用^
[root@www1 ~]# cat i.txt 
a+c
a-c
a*c
a/c
a1c
a2c
a!c
[root@www1 ~]# grep 'a[!+*/-]c' i.txt 
a+c
a-c
a*c
a/c
a!c
[root@www1 ~]# grep 'a[^!+*/-]c' i.txt 
a1c
a2c

+
[root@tencent_cloud test]# cat a.txt 
a
ab
abbcccc
abbbbbbbbbbbbbbbbccc
bbbbbbbbbbbbb
aaaaaaaaaaaaaaaab
[root@tencent_cloud test]# grep -n "ab*" a.txt 
1:a
2:ab
3:abbcccc
4:abbbbbbbbbbbbbbbbccc
6:aaaaaaaaaaaaaaaab
[root@tencent_cloud test]# egrep -n 'ab+' a.txt 	#这里要配合egrep或者grep -E使用
2:ab
3:abbcccc
4:abbbbbbbbbbbbbbbbccc
6:aaaaaaaaaaaaaaaab
[root@tencent_cloud test]# grep -En 'ab+' a.txt 
2:ab
3:abbcccc
4:abbbbbbbbbbbbbbbbccc
6:aaaaaaaaaaaaaaaab

jio本中的用法

#!/bin/bash

while true
do
        read -p "请输入用户名>>:" inp_name
        read -p "请输入用户密码>>:" inp_pwd
        if [[ $inp_pwd =~ ^[0-9]+$ ]];then	
       	#这里正则作为if的条件的时候需要加双[],等于的时候需要用=~
                echo "登录成功"
                break
        else
                echo "请输入数字,小垃圾"
                continue 
        fi
done

sed

定位到某一行,将某一行的某一部分给替换掉

定位到某一行,然后删除

定位到某一行,在该行后添加新的配置

语法

#定位
sed -r "定位+操作" test.txt		#-r启用扩展正则表达式,""内是规则
sed -r "3,5+操作" test.txt	#第三行到第五行进行操作
sed -r "3+操作;5+操作" test.txt	#第三行和第五行
sed -r "/正则/+操作" test.txt	#正则定位行

#操作
g	#从左换到右
i	#忽略大小写

场景1

定位到某一行替换掉

定位到某一行可以用行号,或者正则

#指定行
[root@tencent_cloud test]# cat a.txt 
egonxxx
egonyyyEGONzz
egon
[root@tencent_cloud test]# sed -r "1s/egon/666/g" a.txt 	#指定行
666xxx
egonyyyEGONzz
egon
[root@tencent_cloud test]# sed -r "/^egon/s/egon/666/gi" a.txt 	#正则指定行
666xxx
666yyy666zz
666

#第一到第三行
[root@tencent_cloud test]# sed -r "1,3s/egon/666/g" a.txt 
666xxx
666yyyEGONzz
666

#第一行和第三行
[root@tencent_cloud test]# sed -r "1s/egon/666/g;3s/egon/666/g" a.txt 
666xxx
egonyyyEGONzz
666

场景二

sed -r "1,3d" new.txt
sed -r "/^[0-9]/d" new.txt

场景三

定位到某一行,在改行后添加新的配置
sed -r "1a XXXXXXXXXXXXXXXX" new.txt

场景四

定位到某一行,将整行修改掉
sed -r "1c XXXXXXXXXXXXXXXX" new.txt

awk

善长做有规律的列处理

语法

-F	#指定分隔符,不指定默认空格
#这里有个注意点,awk全部使用''
awk -F: '定位{}' 文件路径

awk -F: 'NR==3{print $1,$7}' /etc/passwd	#第三行第一列和第七列
awk -F: 'NR>=3 && NR<=5{print $0}' /etc/passwd	#第三行到第五行(包含)
awk -F: 'NR==3 || NR==5{print $1,$3}' /etc/passwd	#第三行或第五行
awk -F '/正则/{print $1"-"$3}'

案例

#第三行第一列和第七列
[root@tencent_cloud test]# awk -F: 'NR==3{print $1,$7}' /etc/passwd
daemon /sbin/nologin

#第三行到第五行(包含)
[root@tencent_cloud test]# awk -F: 'NR>=3 && NR<=5{print $0}' /etc/passwd
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@tencent_cloud test]# awk -F: 'NR==3 || NR==5{print $0}' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

#bash结尾的
[root@tencent_cloud test]# awk -F: '/bash$/{print $1,$7}' /etc/passwd
root /bin/bash
lighthouse /bin/bash
mysql /bin/bash
baimo /bin/bash

获取ip地址

[root@tencent_cloud test]# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.12.9  netmask 255.255.252.0  broadcast 10.0.15.255
        inet6 fe80::5054:ff:fe86:a5f1  prefixlen 64  scopeid 0x20<link>
        ether 52:54:00:86:a5:f1  txqueuelen 1000  (Ethernet)
        RX packets 24632239  bytes 34222692429 (31.8 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3648904  bytes 666552359 (635.6 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@tencent_cloud test]# ifconfig eth0 | awk 'NR==2{print $2}'
10.0.12.9
[root@tencent_cloud test]# ip=`ifconfig eth0 | awk 'NR==2{print $2}'`
[root@tencent_cloud test]# echo $ip
10.0.12.9

expect

安装

yum install expect -y

基本语法格式

expect << EOF
	需要交互的代码块
	expect{
	"询问1"{send "操作\r(确认)";exp_continue}
	"询问2"{send "操作\n(确认)";exp_continue}
	"询问3"{send "操作\n"}
	}
	expect eof

EOF

远程连接并执行命令jio本

[root@www1 scripts]# cat 15.sh 
#!/bin/bash

expect << EOF
    spawn ssh root@1.1.1.2 hostname

    expect {
	    "yes/no" {send "yes\r";exp_continue}
	    "*assword" {send "1\n"}
    }

    expect eof

EOF
[root@www1 scripts]# chmod +x 15.sh 
while read line	#line是一个变量给你用
do
echo $line>>./b.txt 
done</etc/passwd	#定义的要阅读的文件路径
#写一个脚本可以远程操作100台主机,并完成该密码操作

1、将需要操作的变量存在一个文件中,文件格式如下:
root:原密码:新密码:ip
root:123:1:192.168.15.100

2、读信息,用awk切出信息

3、使用expect免交互
#!/bin/bash/expect

while read line
do
user=`echo $line | awk -F: '{print $1}'` #user
old_pwd=`echo $line | awk -F: '{print $2}'` #old password
new_pwd=`echo $line | awk -F: '{print $3}'` #new password
ip=`echo $line | awk -F: '{print $4}'` #ip

expect << EOF
    spawn ssh $user@$ip passwd

    expect {
            "yes/no" {send "yes\r";exp_continue}
            "*assword" {send "$old_pwd\n"}
    }
    expect {
            "*assword" {send "$new_pwd\n";exp_continue}
            "*assword" {send "$new_pwd\n"}

    }
    expect eof

EOF
done</tmp/passwd.txt
posted @ 2021-04-13 19:01  BaiM0  阅读(288)  评论(0编辑  收藏  举报