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