grep 正则表达式 sed awk expect

  • 今日内容
  1. grep : 过滤
  2. sed :非交互式编辑文本
  3. awk :格式化处理有规律的文本
  4. expect : expect帮忙处理交互

三剑客命令的共性 :
1. 都支持正则表达式
2. 都支持管道

- 非交互式改密码
echo 123 | passwd nana --stdin 
# Changing password for user egon.
# passwd: all authentication tokens updated successfully.

grep命令

grep命令主要用于过滤文本,grep家族如下:
grep:在文件中全局查找指定的正则表达式,并打印所有包含该表达式的行
egrep:扩展的egrep,支持更多的正则表达式元字符
fgrep:固定grep(fixed grep),有时也被称作快速(fast grep),它按字面解释是所有的字符
  • grep运行原理
方式1 : 直接从文件中过滤
grep "root" /etc/passwd
# root:x:0:0:root:/root:/bin/bash

方式2 : 通过管道进行过滤
cat /etc/passwd | grep "root"			
tasklist | findstr cmd		windows系统中也可以通过管道进行过滤(findstr=grep)		

打开文件,每读一行,都用正则表达式去匹配一下,但凡匹配成功一次,该行就被过滤出来
  • grep的选项
head -10 /etc/passwd > test.txt

-n  过滤结果带有行号
grep -n "root" test.txt
# 1:root:x:0:0:root:/root:/bin/bash
# 10:operator:x:11:0:operator:/root:/sbin/nologin

-o  只显示匹配成功的内容
grep -o "root" test.txt
# root
# root
# root
# root

-q  静默输出(grep会默认把结果输出在终端,静默输出适用于写脚本文件)
vim test.txt
	方法1 : grep "root" /etc/passwd &>/dev/null		
	方法2 : grep -q "root" /etc/passwd				
	if [ $? -eq 0 ];then
	        echo "ok"
	else
	        echo "no"
	fi
	
./a.txt
# ok

--color 		输出结果加颜色
alias grep			grep命令默认输出结果是自带颜色的
# alias grep='grep --color=auto'

-i		 忽略大小写
grep -i "root" test.txt
# ROOT:x:0:0:root:/root:/bin/bash
# operator:x:11:0:operator:/Root:/sbin/nologin

-A 2		过滤成功的后两行显示
grep -A 2 "root" test.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

-B 2		过滤成功的前两行显示
grep -B 2 "root" test.txt
# 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

-C 2		过滤成功的前后两行都显示
grep -C 2 "root" test.txt
# bin:x:1:1:bin:/bin:/sbin/nologin
# daemon:x:2:2:daemon:/sbin:/sbin/nologin
# root: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

-c			显示过滤成功的行数
grep -c "root" test.txt
# 3

-v			取反
grep -v "root" test.txt			显示除了包含root以外的其他所有行
# bin:x:1:1:bin:/bin:/sbin/nologin
# daemon:x:2:2:daemon:/sbin:/sbin/nologin

-w 			匹配单词
 ps -ef | grep ssh			匹配所有包含ssh的进程
# root       1376      1  0 15:26 ?        00:00:00 /usr/sbin/sshd -D
# root       1623   1376  0 15:26 ?        00:00:00 sshd: root@pts/0
# root       1659   1625  0 15:27 pts/0    00:00:00 grep --color=auto ssh

ps -ef | grep -w ssh		匹配所有包含ssh单词的进程
# root       1663   1625  0 15:28 pts/0    00:00:00 grep --color=auto -w ssh

-l			匹配成功,则只将文件名打印出来,失败则不打印(通常-rl一起用)
-R,-r		递归
grep -rl "passwd" /etc				显示/etc目录下包含passwd字符串的文件名
# /etc/login.defs
# /etc/selinux/semanage.conf
# /etc/selinux/targeted/contexts/files/file_contexts

正则表达式

  • 正则表达式 :用特殊的符号指定规则
^		以什么开头开始匹配(只匹配开头)
grep -n "^root" test.txt
# 4:root:x:3:4:adm:/var/adm:/sbin/nologin

$		从结尾结尾开始匹配(只匹配结尾)
grep -n "root$" test.txt
# 5:lp:x:4:7:lp:/var/spool/lpd:/sbin/root
cat c.txt
# abc 
# a+c
# a-c
# a1c
# aaaaaac
# abbbbcc
# ccacccc
# dddddab

.			匹配任意一个字符
grep "a.c" c.txt
# abc 
# a+c
# a-c
# a1c
# aaaa(aac)
# cc(acc)cc

*			左边的个字符出现0次或者无数次
grep "ab*" c.txt
# (ab)c 
# (a)+c
# (a)-c
# (a)1c
# (aaaaaa)c
# (abbbb)cc
# cc(a)cccc
# ddddd(ab)

.*			匹配没有或者所有(贪婪模式)
grep "a.*c" c.txt
# abc 
# a+c
# a-c
# a1c
# aaaaaac
# abbbbcc
# cc(acbcc)				贪婪模式,以最远的c为准

.*?			非贪婪模式
vim d.txt				 需求 : 过滤出域名
	< a href="www.baidu.com">我是百度</ a>< a href="http://www.sina.com.cn">新浪</ a>

grep -oP '".*?"' d.txt	   -o(只显示匹配成功的内容)  -P(显示非贪婪模式的结果)  .*?(固定用法,将贪婪模式变成非贪婪模式)
# "www.baidu.com"
# "http://www.sina.com.cn"

[]			匹配指定范围的任意一个字符
grep "a[a-zA-Z]c" c.txt			匹配a和c之间,包含的任意一个字符(不区分大小写)
# abc 
# aaaaaac
注意 : -号只能放在最左边或者最右边 ; ^号在[]里面表示取反的意思

+ 			左边的字符出现1次或者无穷次,(扩展政策,只能配合egrep一起使用)
egrep -n "ab+" c.txt
# 1:abc 
# 6:aaabbbbcc
# 8:dddddab
注意 : * 号与 + 号的差别,*号表示左边的字符出现0次或者无穷次
  • 案例
- 需求:判断用户输入的是否是数字
vim test.txt
	# !/bin/bash

	while true
	do
	        read -p "输入年龄" age
	
	        if [[ $age =~ ^[0-9]+$ ]];then		判断正则必须加[],等于正则表达式=~,以数字开头以数字结尾(数字出现一次或者无穷次)
	                echo "pass"
	                break
	        else
	                echo "输入数字啊,弟弟"
	        fi
	done
	
	echo "后续代码"

sed命令

- sed常用的场景
场景1:
定位到某一行,然后将该行的某一部分给替换掉
- 格式 
sed -r "定位 + 操作" test.txt

sed -r "3 操作" test.txt					定位到第3行进行操作
sed -r "3,5 操作" test.txt				定位到第3行到第5行进行操作
sed -r "1 操作;3操作" test.txt			定位到第1行和第3行进行操作

场景2:
定位到某一行,然后删除
sed -r "1,3d" test.txt					删除第1行到第3行

场景3:
定位到某一行,在该行下一行添加新的内容
sed -r "1a 123" test.txt				在第一行的下一行写入123

场景4:
定位到某一行,将整行替换掉
sed -r "1c aaa" test.txt				将第一行的内容替换成aaa

- sed(流逝编辑器) 底层原理
从硬盘把文件内容(一行一行读取)读入到内存,在内存中根据你制定的规则修改原文件。
修改好原文件后把结果输出到终端。默认情况下是不修改原文件!!!(修改原文件内容需要加选项 -i )

  • sed命令使用
1. 通过行号来进行定位
cat test.txt
# xxxnanaxxxxnanaxxx
# NAnaxxxxNANAxxxxxx
# xnanaxxxxxnanaxxxx
# NANAxxxxNANaxxxxxx

 s/old/new/gi  i(忽略大小写),g(从左一直匹配到右)
sed -r "2s/nana/666/gi" test.txt			将第二行的nana替换成666
# xxxnanaxxxxnanaxxx
# 666xxxx666xxxxxx
# xnanaxxxxxnanaxxxx
# NANAxxxxNANaxxxxxx

sed -r "2,4s/nana/666/gi" test.txt			将第二行到第四行的nana替换成666
# xxxnanaxxxxnanaxxx
# 666xxxx666xxxxxx
# x666xxxxx666xxxx
# 666xxxx666xxxxxx

sed -r "2s/nana/666/gi;4s/nana/666/gi" test.txt			将第二行和第四行的nana替换成666
# xxxnanaxxxxnanaxxx
# 666xxxx666xxxxxx
# xnanaxxxxxnanaxxxx
# 666xxxx666xxxxxx

2. 通过正则来进行定位(针对一些不规律的配置文件)
cat test.txt
# 1xxxnanaxxxxnanaxxx
# 2NAnaxxxxNANAxxxxxx
# xnanaxxxxxnanaxxxx
# 4NANAxxxxNANaxxxxxx

sed -r "/^[a-zA-Z]/s/nana/666/gi" test.txt			将以字母开头的行nana替换成666			
# 1xxxnanaxxxxnanaxxx
# 2NAnaxxxxNANAxxxxxx
# x666xxxxx666xxxx
# 4NANAxxxxNANaxxxxxx


- 删除
sed -r "1,3d" test.txt						删除第一行到第三行
# 4NANAxxxxNANaxxxxxx

sed -r "/^[0-9]/d" test.txt					删除以数字开头的行
# xnanaxxxxxnanaxxxx

- 定位行的下一行添加内容
sed -r "1a 123" test.txt 
# 1xxxnanaxxxxnanaxxx
# 123
# 2NAnaxxxxNANAxxxxxx
# xnanaxxxxxnanaxxxx
# 4NANAxxxxNANaxxxxxx

- 替换定位行的内容
sed -r "1c aaa" test.txt
# aaa
# 2NAnaxxxxNANAxxxxxx
# xnanaxxxxxnanaxxxx
# 4NANAxxxxNANaxxxxxx

awk命令

- 格式
awk -F: 'NR==定位的行号{操作}' 文件路径			
awk -F: 'NR>行号 && NR<行号{操作}' 文件路径
awk -F: 'NR==行号 || NR==行号{操作}' 文件路径
	-F  指定分隔符(不写默认为空格)

注意 : 我们在指定文件的行号和操作时,只能使用单引号。
1. 指定行来进行定位
awk -F: 'NR==3{print $1,$7}' /etc/passwd		指定第三行,以:进行分割,打印第1段和第7段的内容
# daemon /sbin/nologin

awk -F: 'NR>3 && NR<5{print $0}' /etc/passwd		指定大于第三行,小于第五行,以:进行分割,打印整行内容($0,代表打印整行)
# adm:x:3:4:adm:/var/adm:/sbin/nologin

awk -F: 'NR==3 || NR==5{print $1}' /etc/passwd			指定第三行或者第五行,以:进行分割,打印第1段内容
# daemon
# lp

awk -F: 'NR==3 || NR==5{print $1"-"$3}' /etc/passwd	   	指定第三行或者第五行,以:进行分割,打印第1段和第3段的内容,中间以-进行连接
# daemon-2
# lp-4
注意 : || 符号,如果指定的行都存在,那就都进行操作;如果指定的行不存在,那就操作存在的行

2. 通过正则来进行定位
awk -F: '/bash$/{print $0}' /etc/passwd				打印以bash结尾,以:进行分割的行
# root:x:0:0:root:/root:/bin/bash
# egon:x:1000:1000::/home/egon:/bin/bash
  • 案例
ifconfig eth0
# eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
#        inet 192.168.80.100  netmask 255.255.255.0  broadcast 192.168.80.255
#        inet6 fe80::1af5:8729:4b78:31f1  prefixlen 64  scopeid 0x20<link>
#        ether 00:0c:29:ca:a8:27  txqueuelen 1000  (Ethernet)
#         RX packets 13062  bytes 1012632 (988.8 KiB)
#         RX errors 0  dropped 0  overruns 0  frame 0
#         TX packets 6938  bytes 922523 (900.9 KiB)
#         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

- 过滤出ifconfig eth0的IP地址
方法1:
ip=$(ifconfig eth0 | awk 'NR==2 {print $2}')		不写-F选项默认以空格为切割
echo $ip
# 192.168.80.100

方法2:
ip=$(ifconfig eth0 | awk '/netmask/{print $2}')			注意:匹配字符串不能在字符串中再加引号
echo $ip
# 192.168.80.100

expect命令

  • 帮忙处理交互
- 免交互编写配置文件
cat>b.txt<<EOF
> 123
> 456
> 789
> EOF
cat b.txt
# 123
# 456
# 789

通过免交互的模式向b.txt中写入数据,输入EOF退出并保存
  • 免交互执行ssh,远程登陆其他服务器配置文件模板
expect << EOF						 
        spawn ssh $user@$ip $cmd
		# 只要是spawn提交的命令都会交给expect软件执行
			
        expect {
                "yes/no" {send "yes\r";exp_continue}	
                # send会自动帮忙提交yes,\r换行符;exp_continue表示继续进行下一步
                "*assword" {send "$password\n"}	
                # send会自动帮忙提交passwd,\n换行符		
        }
        expect eof
EOF
  • 修改其他虚拟机的主机名
1. 安装expect命令
yum -y install expect

2. 写入配置文件
vim a.sh
	user="root"
	ip="192.168.80.120"
	cmd="hostname"
	passwd=123
	
	expect << EOF
	        spawn ssh root@192.168.80.120 hostname
	                        
	        expect {
	                "yes/no" {send "yes\r";exp_continue}    
	                "*assword" {send "123\n"}               
	        }
	
	        expect eof
	EOF

./a.sh
# spawn ssh root@192.168.80.120 hostname
# root@192.168.80.120's password: 
# svr7
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值