您的位置:首页 > 运维架构 > Shell

SHELL-expect、正则表达式和sed的使用

2016-05-20 10:55 671 查看
本节所讲内容:

•      实战:expect实现无交互登录

•      正则表达式

•      sed

•      awk 

•      awk高级应用

•      cut

 

expect是在tcl基础上创建起来的,它还提供了一些tcl所没有的命令,它可以用来做一些linux下无法做到交互的一些命令操作

 

安装expect

[root@xuegod60 ~]# yum -yinstall expect

也可以通过源码包的方式进行安装

源码下载链接

http://jaist.dl.sourceforge.net/project/tcl/Tcl/8.6.4/tcl8.6.4-src.tar.gz

http://sourceforge.net/projects/expect/files/Expect/5.45/expect5.45.tar.gz/download

 

使用expect创建脚本的方法

1)定义脚本执行的shell

#!/usr/bin/expect

这里定义的是expect可执行文件的链接路径(或真实路径),功能类似于bash等shell功能

 

2)set timeout 30

设置超时时间,单位是秒,如果设为timeout -1 意为永不超时

 

3)spawn

spawn 是进入expect环境后才能执行的内部命令,不能直接在默认的shell环境中进行执行

主要功能:传递交互指令

 

4)expect

这里的expect同样是expect的内部命令

主要功能:判断输出结果是否包含某项字符串,没有则立即返回,否则就等待一段时间后返回,等待时间通过timeout进行设置

 

5)send

执行交互动作,将交互要执行的动作进行输入给交互指令

命令字符串结尾要加上"r",如果出现异常等待的状态可以进行核查

 

6)interact

执行完后保持交互状态,把控制权交给控制台

如果不加这一项,交互完成会自动退出

 

7)exp_continue

继续执行接下来的交互操作

 

8)$argv

expect 脚本可以接受从bash传递过来的参数,可以使用 [lindex $argv n]获得,n从0开始,分别表示第一个,第二个,第三个……参数

 

[root@xuegod60 ~]# vimssh.exp

#!/usr/bin/expect

set ipaddress"192.168.1.61"

set passwd"123456"

set timeout 30

spawn ssh root@$ipaddress

expect {

"yes/no" { send"yes\r";exp_contine }

"password:" {send "$passwd\r"}

}

interact

 

执行验证

[root@xuegod60 ~]#./ssh.exp

spawn sshroot@192.168.1.61

root@192.168.1.61'spassword:

Last login: Sat Mar 1207:55:41 2016 from 192.168.1.60

 

2)通过调用bash的位置参数实现ssh远程登录

[root@xuegod60 ~]# vimssh2.exp

#!/usr/bin/expect

set ipaddress [ lindex $argv0 ]

set user [ lindex $argv 1]

set passwd [ lindex $argv2 ]

set timeout 30

spawn ssh$user@$ipaddress

expect {

"yes/no" { send"yes\r";exp_contine }

"password:" {send "$passwd\r"}

}

interact

 

[root@xuegod60 ~]#./ssh2.exp 192.168.1.61 rm 123456

spawn ssh rm@192.168.1.61

 

正则表达式的使用

正则表达式,又称正规表示法、常规表示法(英语:RegularExpression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。

 

是指一个用来描述或者匹配一系列符合某个句法规则的字符的那个字符串。

用某种模式去匹配一类字符串。

aaa=123

使用grep

-i  忽略大小写

-v 反转

-n  显示行号

 

1.    正则表达式中特殊字符

(1) ^word:待搜寻的字符串(word)在行首!

[root@xuegod60 ~]# grep"^sync" /etc/passwd

sync:x:5:0:sync:/sbin:/bin/sync

(2)word$:待搜寻的字符串(word)在行尾!

[root@xuegod60 ~]# grep"shutdown$" /etc/passwd --color

shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

(3)\:将特殊符号的特殊意义去除

例:搜寻包括单引号 '的行,并把行号也打印出来

[root@xuegod60 ~]# grep-n \' passwd

8:halt:x:7:0:'halt':/sbin:/sbin/halt

9:'mail':x:8:12:mail:/var/spool/mail:/sbin/nologin

 

[root@xuegod60 ~]# grep-n "'" passwd

8:halt:x:7:0:'halt':/sbin:/sbin/halt

9:'mail':x:8:12:mail:/var/spool/mail:/sbin/nologin

 

(4)*:重复零个到无穷多个的前一个字符

搜寻包括sp,后面o重复2次以上的行。  记得要写两个o
[root@xuegod60 ~]# grepspoo* passwd

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

'mail':x:8:12:mail:/var/spool/mail:/sbin/nologin

"uucp":x:10:14:uucp:/var/spool/uucp:/sbin/nologin

postfix:x:89:89::/var/spool/postfix:/sbin/nologin

 

(5)[list]:字符集合,里面列出想要选择的字符

搜寻包括ga或者go的行:

[root@xuegod60 ~]# grepg[ao] passwd

games:x:12:100:games:/usr/games:/sbin/nologin

gopher:x:13:30:gopher:/var/gopher:/sbin/nologin

 

(6)搜寻不以#号开头的行:

[root@xuegod60 ~]# grep^[^#] passwd

 

(7)[n1-n2]:字符集合的,里面列出想要包括的字符范围!

搜寻含有数字的3到5的行:

[root@xuegod60 ~]# grep [3-5]passwd

 

2.找出开始为大写字母的:

[root@xuegod60 ~]# grep ^[A-Z]passwd

Mk2:x:502:500::/home/mk:/bin/bash

Mk3:x:503:500::/home/mk:/bin/bash

 

那如果我不想要开头是英文字母:  ^[^#]

[root@xuegod60 ~]# grep^[^a-zA-Z] passwd

 

显示空白行的行号

[root@xuegod60 ~]# grep -n ^$passwd

50:

3.正则表达式中。“.”代表绝对有一个任意字符的意思;而“*”代表重复前一个字符到无穷次的意思。

  任长度的字符表示方法: .*

寻找包括有r开头和t结束且长度为四个字符行:

 

[root@xuegod60 ~]# grep r..tpasswd

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

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

ftp:x:14:50:FTPUser:/var/ftp:/sbin/nologin

 

寻找oo,ooo, oooo 等等的数据,也就是说,至少要有两个o 以上:

[root@xuegod60 ~]# grep ooo*passwd

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

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

'mail':x:8:12:mail:/var/spool/mail:/sbin/nologin

 

寻找包括g开头和g结束的字符串,中间可有可无

[root@xuegod60 ~]# grep^g.*g passwd

games:x:12:100:games:/usr/games:/sbin/nologin

gopher:x:13:30:gopher:/var/gopher:/sbin/nologin

gdm:x:42:42::/var/lib/gdm:/sbin/nologin

 

扩展

\? 用于修饰前导字符,表示前导字符出现0或1次

\+ 用于修饰前导字符,表示前导字符出现1或多次   例:a\+匹配1或多个a

\{n,m\}  用于修饰前导字符,表示前导字符出现n至m次(n和m都是整数,且n<m)

例:a\{3,5\}匹配3至5个连续的a

 

精确匹配:

#grep '\<匹配内容\>' filename

[root@xuegod60 ~]# grep'\<root\>' passwd

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

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

 

sed

strem editor  流编辑器

sed编辑器是一行一行的处理文件内容的。正在处理的内容存放在模式空间(缓冲区)内,处理完成后按照选项的规定进行输出或文件的修改。

 

sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;

 

sed  [options] ‘[command]’  [filename]

[root@xuegod60 ~]# sed's/root/rm/' /etc/passwd > newfilename

/../../       分隔符

分割符"/" 可以用别的符号代替 , 比如 “,”   “|”   “_“等 .

 

[root@xuegod60 ~]# sed's_/bin/bash_/sbin/nologin_' b.txt

/sbin/nologin

显然 , 此时用 "_" 作分割符比 "/" 好得多

 

用 & 表示匹配的字符串

[root@xuegod60 ~]# sed's/root/(&)/' /etc/passwd > b.txt

 

sed 默认只替换搜索字符串的第一次出现 , 利用 /g 可以替换搜索字符串所有

 

同时替换多项内容:-e

[root@xuegod60 ~]# sed -e'3,5s/nologin/bash/' -e '9,11s/sbin/bin/' passwd > b.txt

 

options:

-n    抑制自动(默认的) 输出 ***  读取下一个输入行

-e    执行多个sed指令
-f     运行脚本

-i     编辑文件内容 ***

-i.bak      编辑的同时创造.bak的备份

-r     使用扩展的正则表达式 ***

command:

a     在匹配后追加 ***

i      在匹配前插入 ***

p     打印 ***

d     删除 ***

r/R  读取文件/一行

w     另存

s      查找

c      替换

y     替换

h/H 复制拷贝/追加模式空间(缓冲区)到存放空间

g/G 粘贴从存放空间取回/追加到模式空间

x     两个空间内容的交换

n/N 拷贝/追加下一行内容到当前

D     删除\n之前的内容

P     打印\n之前的内容

b     无条件跳转

t      满足匹配后的跳转

T     不满足匹配时跳转

 

1.显示文件第三行

[root@xuegod60 ~]# sed -n'3p' passwd

daemon:x:2:2:daemon:/sbin:/sbin/nologin

 

2.显示文件前三行

[root@xuegod60 ~]# sed -n'1,3p' passwd

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

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

 

3.显示文件除前三行之外的全部内容

[root@xuegod163 test]#sed -n '1,3!p' passwd

 

4. 显示文件第三行和之后的三行

[root@xuegod60 ~]# sed -n'3,+3p' 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

sync:x:5:0:sync:/sbin:/bin/sync

 

在文件头插入“###”

[root@xuegod60 ~]# sed'1i###' passwd

 

在文件尾插入"@@@"

[root@xuegod60 ~]# sed'$a@@@' passwd

 

 

在文件的第二行后插入两行内容

[root@xuegod60 ~]# sed'2a hello \

> how are your?'passwd

 

把文件第三行替换成“$$$”

[root@xuegod60 ~]# sed '3c$$$'passwd

扩展:nl命令在linux系统中用来计算文件中行号。nl 可以将输出的文件内容自动的加上行号

[root@xuegod60 ~]#nl  /etc/passwd  | sed '2ahello'

 

注意:

sed 的-i选项可以直接修改文件中的内容

[root@xuegod60 ~]# sed -i's/root/rm/' passwd

 

复制粘贴

把文件的第二行到第四行复制到文件的末尾

[root@xuegod60 ~]# sed'2,4H;$G' passwd > b.txt

h/H 复制拷贝/追加模式空间(缓冲区)到存放空间

g/G 粘贴从存放空间取回/追加到模式空间

 

例子:

删除空行    d 删除 ***

[root@xuegod60 ~]# sed'/^$/d' passwd  > c.txt

 

把fstab中包含xfs的记录(行)写入新的文件中

[root@xuegod60 ~]# sed'/xfs/w newfstab' /etc/fstab

awk
AWK是一种优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一。这种编程及数据操作语言的最大功能取决于一个人所拥有的知识。awk命名:Alfred
Aho Peter Weinberger和brian kernighan三个人的姓的缩写。

 
最简单地说, AWK 是一种用于处理文本的编程语言工具。
任何awk语句都是由模式和动作组成,一个awk脚本可以有多个语句。模式决定动作语句的触发条件和触发时间。
 
特殊字段:
BEGIN语句设置计数和打印头部信息,在任何动作之前进行。
END语句输出统计结果,在完成动作之后执行。
 
分隔符默认是空格,可以用-F, 改变成逗号为分隔符
-F, 或改成冒号 -F:

[root@localhost ~]# rpm -qf `which awk`
gawk-4.0.2-4.el7.x86_64
[root@localhost ~]# rpm -qf `which cut`
coreutils-8.22-11.el7.x86_64
 
例子:
例1.获取当前主机网卡的ip地址
[root@localhost ~]# ipaddress=$(ifconfig | grep broadcast | awk '{print $2}')
 
例2:打印出passwd中用户UID大于1000的用户名和登录shell
[root@localhost ~]# cat /etc/passwd | awk -F: '$3>1000 {print $1 "\t" $7}'
nfsnobody /sbin/nologin
rm1 /bin/bash
rm2 /bin/bash
rm3 /bin/bash
 
多条件进行过滤
例3:
[root@localhost ~]# cat /etc/passwd | awk -F: 'BEGIN {print "name \t shell"}$3>1000 && $7=="/bin/bash" {print $1 "\t" $7} END
{print "Thank you!!!"}'

name shell
rm1 /bin/bash
rm2 /bin/bash
rm3 /bin/bash
Thank you!!!
 
例4:awk在脚本中的使用
找到系统中所有的能登录的普通用户,并进行删除
#!/bin/bash
user=$(cat /etc/passwd | awk -F: '$3>=1000 && $7=="/bin/bash" {print$1}')
for i in $user
do
  userdel -r $i
done
 
RHEL7中查看系统当前内存使用百分比
[root@xuegod163 ~]# vim usecache.sh
#!/bin/bash
echo "此脚本可以用来查看当前内存使用百分比"
use=$(free -m | grep "Mem:"
| awk '{print $3}')

total=$(free -m | grep "Mem:" | awk '{print $2}')
useper=$(expr $use \* 100 / $total)
echo "系统当前内存使用百分比为:"
echo ${useper}%
 
执行结果
[root@localhost ~]# sh usercache.sh
此脚本可以用来查看当前内存使用百分比
系统当前内存使用百分比为:
10%
 
Cut
cut是一个选取命令,就是将一段数据经过分析,取出我们想要的。一般来说,选取信息通常是针对“行”来进行分析的,并不是整篇信息分析的。
主要参数

-b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n
标志。

-c :以字符为单位进行分割。

-d :自定义分隔符,默认为制表符。

-f  :与-d一起使用,指定显示哪个区域。

 
例1:以字节进行分割
[root@localhost ~]# tail -3 /etc/passwd | cut -b 1-4,11,12
post89
sshd74
tcpd72
 
例二:以字符进行分割
[root@localhost ~]# cat newyear.txt | cut -c 1-4
新年好,
 
例3:以空格作为分隔符
[root@localhost ~]# sed -n l c.txt
aaaa\tbbbb cccc$
aaaa bbbb\tcccc$
[root@localhost ~]# cat c.txt | cut -d ' ' -f 1
aaaa bbbb
aaaa
 
总结:
cut有哪些缺陷和不足?
如果文件里面的某些域是由若干个空格来间隔的,那么用cut就有点麻烦了,因为cut只擅长处理“以一个字符间隔”的文本内容
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: