Shell编程——三剑客
- 简介
Grep:默认不支持扩展表达式,加-E或者egrep
Awk:支持所有zhengze
Sed默认不支持扩展表达式,加-r
2.sed语法格式
Sed 选项 命令 文件(注意sed命令和文件之间空格)
- 工作原理:sed读取一行,首先将其放入缓存。然后处理,处理后,将缓存区的内容发送到终端,存储sed的内容的缓存区称之为模式空间。
Sed -e 多点操作
-r 使用扩展正则使用
-i接修改内容(如果不使用-i选项只是修改内存中的数据,不会影响磁盘文件)
-n 取消默认的文件输出,和p连用
a 追加到后面一行输出文本
c 取代指定的行
i 在制定行前添加(注意和-i的区别)
!指定行以外所有行应用(取反)
d 指定删除的行(如果不指定就默认匹配所有行)
s/目标内容/替换内容/g
p打印选中的行
awk详解
- 定义:用来处理和生成报告
- 格式: awk 参数 ‘条件 动作’
1. NR 行 (行数)
NF 字段(个数)
-F 指定分隔符
$n 输出一个制定的字段
$NF 输出最后一个字段
$0 输出整条记录
awk特殊模式-BEGIN模式与END模式
BEGIN模块再awk读取文件之前就执行,一般用来定义我们的内置变量(预定义变量,eg:FS,RS)
需要注意的是BEGIN模式后面要接跟一个action操作块,包含在大括号内。awk必须在输入文件进行任何处理前先执行BEGIN里的动作(action)。我们可以不要任何输入文件,就可以对BEGIN模块进行测试,因为awk需要先执行完BEGIN模式,才对输入文件做处理。BEGIN模式常常被用来修改内置变量ORS,RS,FS,OFS等值。
EHD在awk读取完所有的文件的时候,再执行END模块,一般用来输出一个结果(累加,数组结果),也可以是和BEGIN模块类似的结尾标识信息
与BEGIN模式相对应的END模式,格式一样,但是END模式仅在awk处理完所有输入行后才进行处理。
shell正则
- shell函数:shell中允许将一组命令集合或语句形成一段可用代码,这些代码块称为shell函数。给这段代码起个名字称为函数名,后续可以直接调用该段代码。
- 格式:fun() { 命令 }
- Shell正则表达式
定义:匹配字符串,为了处理大量得文本和字符串指定的一套规则和方法。
分类:基础正则和扩展正则(+ ? | () )
正则与通配的区别:
1) 三剑客awk sed egrep都是正则
2) 文件目录名——通配符 ; 文件内容(字符串,文本内容)——正则表达式
. 匹配任意单个字符
^ 匹配前面字符串开头
$ 匹配前面字符串结尾
*匹配前一个字符的零个或多个
.*表示任意长度的任意字符
+表示前面的字符初选最少一次的情况
?表示前面字符出现最多一次
[ ]表示范围内的一个字符
[.-.]匹配括号里的任意一个字符
^[^] 匹配[^]字符之外的任意一个字符
{n,m}表示最少n次 最多m次
>锚定单词尾部
<锁定单词首部
( )调用前面第一个分组
| 或
例:打印出包含某个关键词的文件(关键词执行脚本时接收)
#!/bin/bash
key=$1
for file in `find / -type f`
do
grep "$key" $file &>/dev/null
if [ $? -eq 0 ];then
echo $file
sleep 1
fi
done
1.查找指定的字符串
例子:显示/etc/passwd中保含root的行(显示模式空间中的内容)
方法1:set '/root/p' /etc/passwd
方法2:cat /etc/passwd | sed '/root/p'
2.在指定的位置做增删
例子:删除以root为开头的行
# sed '/^root/d' a.txt
例子:在包含root的行后添加一行 i am ken
# sed '/root/a i am ken' a.txt
3.按行替换
例子:将5到9行的内容替换为 i am ken
# sed '5,9c i am ken' a.txt
4.按照字符替换
例子:将/etc/selinux/config中的SELINUX=enforcing改成 disabled
写法1:# sed -i 's/SELINUX=disabled/SELINUX=enforcing/g' config
写法2:# sed -r -i 's/(SELINUX=)disabled/1enforcing/g' config
5.查找指定的内容再做替换
例子:将以r开头的行中的oo替换为qq
# sed '/^r/{s/oo/qq/g}' passwd
6.多点编辑
例子:去除文件中的注释行和空白行
# grep -v -E "(^#)|(^$)" passwd.bak >passwd
# cat passwd.bak | sed -e '/^#/d' -e '/^$/d' >passwd
7)取反操作
显示非1-3行
# sed -n '1,3!p' passwd
实战: 取出网卡IP地址(企业面试题)
[root@ken ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
link/ether 00:0c:29:99:ea:a6 brd ff:ff:ff:ff:ff:ff
inet 172.20.10.6/24 brd 172.20.10.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 2408:84f4:86:47e1:20c:29ff:fe99:eaa6/64 scope global mngtmpaddr dynamic
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe99:eaa6/64 scope link
valid_lft forever preferred_lft forever
第一种方法:
[root@ken ~]# ip a | awk -F ' +' 'NR==9{print $3}' | awk -F '/' '{print $1}'
172.20.10.6
第二种方法:
[root@ken ~]# ip a | grep -E '^ +.*inet>.*' | awk -F ' +|/' 'NR==2{print $3}'
172.20.10.6
第三种方法:
[root@ken ~]# hostname -i | awk -F ' ' '{print $3}'
172.20.10.6
第四种方法:
[root@ken ~]# ip a | grep brd.*glo | awk -F ' +|/' '{print $3}'
172.20.10.6
第五种方法:
[root@ken ~]# ip a | grep "scope" | awk 'NR==3{print $0}' | awk -F "( |/)+" '{print $3}'
172.20.10.6