shell 元字符
^ 行首定位符
$ 行尾定位符
. 任意单个字符
1. 匹配前导符0到多次
.* 任意多个字符
[] 匹配指定范围内的一个字符
[-] 匹配指定范围内的一个字符
[^] 匹配不在指定组内的字符
\ 用来转义元字符 (” “” )
\< > 词首和词尾定位符
() 匹配稍后使用的字符的标签
x{m} 字符x重复出现m次
x{m,} 字符x重复出现m次以上
x{m,n}字符x重复出现m到n次
2. 匹配一个或多个前导字符
? 匹配零个或一个前导字符
a|b 匹配a或b
grep
过滤,查找文档中的内容 :grep 选项 匹配模式 文件
1. grep 支持基本正则
2. egrep 支持扩展正则
3. fgrep 不支持正则
返回值:
- 0 表示找到内容
- 1 表示没找到内容
- 2 表示找的目录不对
常用选项:
-q 静默查询结果
-v 取反查询
-R 递归查询目录下的文件
-A2 显示查询内容及后2行
-B2 显示查询内容及前2行
-C2 显示查询内容及前后各2行
egrep -l 只显示有查询内容的文件名
egrep -n 查询结果带行号
sed 流编辑
sed 是一种在线的、非交互式的编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。
文本文件->“模式空间”(pattern space)->屏幕
逐行处理
内容未变
编辑文件
格式:sed 选项 [模式]命令 文件
常用选项:
-r 支持正则
-i 直接修改文件内容
-n 静默输出
常用命令:
p 打印
d 删除
s 替换
c 整行替换
a 追加
i 插入
r 读文件
w 写文件
返回值:只有0,不管对错
awk
用来切割和统计
语法:awk 选项 ‘BEGIN{} {} END{}’ 文件名
原理:
(1)awk使用一行作为输入,并将这一行赋给内部变量$0,每一行也可称为一个记录,以换行符结束
(2)然后,行被:(默认为空格或制表符)分解成字段(或域),每个字段存储在已编号的变量中,从$1开始,
最多达100个字段
(3)awk输出之后,将从文件中获取另一行,并将其存储在$0中,覆盖原来的内容,然后将新的字符串分隔
成字段并进行处理。该过程将持续到所有行处理完毕
模式和动作:
任何awk语句都由模式和动作组成。模式部分决定动作语句何时触发及触发事件。处理即对数据进行的操作。如果省略模式部分,动作将时刻保持执行状态。
模式可以是任何条件语句或复合语句或正则表达式。
模式包括两个特殊字段 BEGIN和END。
BEGIN语句使用在任何文本浏览动作之前
END语句用来在awk完成文本浏览动作后打印输出文本总数和结尾状态。
条件表达式: awk -F: ‘{ if() {} }’ /etc/passwd
[root@localhost ~]# awk -F: '{ if($3<5) {print $0} }' /etc/passwd
root:x:::root:/root:/bin/bash
bin:x:::bin:/bin:/sbin/nologin
daemon:x:::daemon:/sbin:/sbin/nologin
adm:x:::adm:/var/adm:/sbin/nologin
lp:x:::lp:/var/spool/lpd:/sbin/nologin
循环:
awk ‘BEGIN{for(i=1;i<=5;i++){print i} }’
awk ‘BEGIN{ i=1; while(i<=10){print i; i++} }’
数组:
awk -F: ‘{username[x++]=$1} END{for(i in username) {print i,username[i]} }’ /etc/passwd
常用案例:
- 统计/etc/passwd中各种类型shell的数量
awk -F: ‘{shells[$NF]++} END{ for(i in shells){print i,shells[i]} }’ /etc/passwd
- 网站访问状态统计 <当前时实状态 netstat>
netstat -ant |grep :80 |awk ‘{access_stat[$NF]++} END{for(i in access_stat ){print i,access_stat[i]}}’
- 统计当前访问的每个IP的连接数量 <当前时实状态 netstat,ss>
ss -an |grep :80 |awk -F”:” ‘!/LISTEN/{ip_count[$(NF-1)]++} END{for(i in ip_count){print i,ip_count[i]}}’ |sort -k2 -rn |head
- 统计Apache/Nginx日志中某一天的PV量 <统计日志>
grep '07/Aug/2012' access_log |awk '{ips[$1]++} END{for(i in ips){print i,ips[i]} }' |awk '$2>100' |sort -k2 -rn