简介
awk是一个文本处理工具,通常用于处理数据并生成结果报告
awk的命名是它的创始人Alfred Aho、Peter Weinberger和Brian Kernighan姓氏的首个字母组成的
工作模式
类似sed,首先读取第一行,处理完后处理下一行,它可以在处理前面加一些数据,处理后面也可以加一些数据
语法格式
- 第一种形式:awk ‘BEGIN{}pattern{commands}END{}’ file_name
BEGIN: 正式处理之前执行
pattern: 匹配模式
commands: 对匹配出来的数据的处理命令
END: 处理完所有匹配数据后执行
file_name: 文件名 - 第二种形式: standard output |awk ‘BEGIN{}pattern{commands}END{}’
standard output表示对标准输出数据进行处理
其他同上
awk的内置变量
| 内置变量 | 含义 |
|---|---|
| $0 | 整行内容 |
| $1-$n | 当前行的第1-n个字段 |
| NF | 当前行的字段个数,也就是有多少列 |
| NR | 当前行的行号,从1开始计数 |
| FNR | 多文件处理时,每个文件行号单独计数,都是从0开始 |
| FS | 输入字段分隔符。不指定默认以空格或tab键分割 |
| RS | 输入行分隔符。默认回车换行\n |
| OFS | 输出字段分隔符。默认为空格 |
| ORS | 输出行分隔符。默认为回车换行 |
| FIL ENAME | 当前输入的文件名字 |
| ARGC | 命令行参数个数 |
| ARGV | 命令行参数数组 |
1 | 1. /etc/passwd 的所有内容显示 |
printf输出
| 格式符 | 含义 |
|---|---|
| %s | 打印字符串 |
| %d | 打印十进制数 |
| %f | 打印一一个浮点数 |
| %X | 打印十六进制数 |
| %o | 打印八进制数 |
| %e | 打印数字的科学计数法形式 |
| %c | 打印单个字符的ASCII码 |
| 修饰符 | 含义 |
|---|---|
| - | 左对齐 |
| + | 右对齐 |
| # | 显示8进制在前面加0 ,显示16进制在前面加0x |
1 | 格式符示例: |
模式匹配
- RegExp(表示可以是一个敞亮字符串或者是一个正则表达式写法)
1
2
3
4匹配/etc/passwd文件行中含有root字符串的所有行
awk 'BEGIN{}/^root/{print $0}' /etc/passwd
匹配/etc/passwd文件行中以yarn开头的所有行
awk 'BEGIN{}/^yarn/{print $0}' /etc/passwd - 关系运算匹配
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30关系运算符匹配:
< 小于
> 大于
<= 小于等于
>= 大于等于
== 等于
!= 不等于
~ 匹配正则表达式
!~ 不匹配正则表达式
不匹配正则表达式
(1)、以:为分隔符, 匹配/etc/passwd文件中第3个字段小于50的所有行信息
awk 'BEGIN{FS=":"}$3<50' /etc/passwd
(2)、以:为分隔符,匹配/etc/passwd文件中 第3个字段大于50的所有行信息
awk 'BEGIN{FS=":"}$3>50' /etc/passwd
(3)、以:为分隔符,匹配/etc/passwd文 件中第7个字段为/bin/bash的所有行信息
awk 'BEGIN{FS=":"}$7=="\/bin\/bash"' /etc/passwd
(4)、以:为分隔符,匹配/etc/passwd文件中 第7个字段不为/bin/bash的所有行信息
awk 'BEGIN{FS=":"}$7=="/bin/bash"' /etc/passwd
(5)、以:为分隔符,匹配/etc/passwd中第3个字段包含3个以上数字的所有行
awk 'BEGIN{FS=":"}$3~/[0,9]{3,}/' /etc/passwd
布尔运算符匹配:
|| 或
&& 与
! 非
(1)、以:为分隔符,匹配/etc/passwd文 件中包含root或mysql的所有行信息
awk 'BEGIN{FS=":"}$1=="root" || $1=="mysql"' /etc/passwd
(2)、以:为分隔符,匹配/etc/passwd文件中第3个字段小于50并且第4个字段大于50的所有行信息
awk 'BEGIN{FS=":"}$3<50 && $4>50' /etc/passwd
动作表达式
| 运算符 | 含义 |
|---|---|
| + | 加 |
| - | 减 |
| * | 乘 |
| / | 除 |
| % | 模 |
| ^或** | 乘方 |
| ++x | 在返回x变量之前, x变量加1 |
| x++ | 在返回变量之后,x变量加1 |
1 | 1、使用awk计算/etc/services中的空白行数量) |
awk条件语句
1 | 1、以:为分隔符,只打印/etc/passwd中第3个字段的数值在50-100范围内的行信息 |
awk循环语句
1 | # 三种循环 |
awk字符函数
| 函数名 | 解释 | 函数返回值 |
|---|---|---|
| length(str) | 计算字符串长度 | 整数长度值 |
| index(str1 ,str2) | 在str1中查找str2的位置 | 返回值为位置索引,从1计数 |
| tolower(str) | 转换为小写 | 转换后的小写字符串 |
| toupper(str) | 转换为大写 | 转换后的大写字符串 |
| substr(str,m,n) | 从str的m个字符开始,截取n位 | 截取后的子串 |
| split(str,arr,fs) | 按fs切割字符串,结果保存arr | 切割后的子串的个数 |
| match(str,RE) | 在str中按照RE查找,返回位置 | 返回索引位置 |
| sub(RE,RepStr,str) | 在str中搜索符合RE的字串,将其替换为RepStr ;只替换第一个 | 替换的个数 |
| gsub(RE,RepStr,str) | 在str中搜索符合RE的字串,将其替换为RepStr;替换所有 | 替换的个数 |
1 | 1、以:为分隔符,返回/etc/passwd中每行中每个字段的长度 |
awk常用选项
| 选项 | 解释 |
|---|---|
| -v | 参数传递 |
| -f | 指定脚本文件 |
| -F | 指定分隔符 |
| -V | 查看awk的版本号 |
1 | # -v |
awk数组与Shell数组
awk数组与Shell数组的区别
前者从0开始,后者从1开始索引
awk数组
格式
1 | array_name[index]=value |
操作
1 | 创建数组 array_name[index]=value |
应用
1 | 1. 统计主机上所有的TCP连接状态数,按照每个TCP状态分类 |
Shell数组
1 | array=("If" "we" "can" "only" "encounter" "each" "other" "rather" "than" "stay" "with" "each" "other,then" "I" "wish" "we" "had never encountered") |
操作
1 | root@ubuntu:~# array=("If" "we" "can" "only" "encounter" "each" "other" "rather" "than" "stay" "with" "each" "other,then" "I" "wish" "we" "had never encountered") |
awk小案例
利用awk处理日志,并生成结果报告
insert.sh生成数据
1 | #!/bin/absh |
需求
1 | (1)、统计每个人员分别插入了多少条record进数据库 |
Shell进行数据库操作
- 学生数据库创建,定义在school.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
DROP TABLE IF EXISTS `db_school`.`Student`;
create table Student
(
Sno varchar(20),
Sname varchar(50),
primary key (Sno)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `db_school`.`Course`;
create table Course
(
Cno varchar(20),
Cname varchar(50),
Tno varchar(20),
primary key (Cno)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `db_school`.`SC`;
create table SC
(
Sno varchar(20),
Cno varchar(20),
score int,
primary key (Sno,Cno)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `db_school`.`Teacher`;
create table Teacher
(
Tno varchar(20),
Tname varchar(50),
primary key (Tno)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `Student`(Sno,Sname) VALUES ('001','陈一');
INSERT INTO `Student`(Sno,Sname) VALUES ('002','郭二');
INSERT INTO `Student`(Sno,Sname) VALUES ('003','张三');
INSERT INTO `Student`(Sno,Sname) VALUES ('004','李四');
INSERT INTO `Student`(Sno,Sname) VALUES ('005','王五');
INSERT INTO `Teacher`(Tno,Tname) VALUES ('001','张老师');
INSERT INTO `Teacher`(Tno,Tname) VALUES ('002','王老师');
INSERT INTO `Teacher`(Tno,Tname) VALUES ('003','钱老师');
INSERT INTO `Teacher`(Tno,Tname) VALUES ('004','刘老师');
INSERT INTO `Teacher`(Tno,Tname) VALUES ('005','胡老师');
INSERT INTO `Course`(Cno,Cname,Tno) VALUES ('001','语文','张老师');
INSERT INTO `Course`(Cno,Cname,Tno) VALUES ('002','数学','王老师');
INSERT INTO `Course`(Cno,Cname,Tno) VALUES ('003','英语','钱老师');
INSERT INTO `Course`(Cno,Cname,Tno) VALUES ('004','物理','刘老师');
INSERT INTO `Course`(Cno,Cname,Tno) VALUES ('005','政治','胡老师');
INSERT INTO `SC`(Sno,Cno,score) VALUES ('001','001',50);
INSERT INTO `SC`(Sno,Cno,score) VALUES ('001','002',60);
INSERT INTO `SC`(Sno,Cno,score) VALUES ('001','003',70);
INSERT INTO `SC`(Sno,Cno,score) VALUES ('001','004',80);
INSERT INTO `SC`(Sno,Cno,score) VALUES ('001','005',90);
INSERT INTO `SC`(Sno,Cno,score) VALUES ('002','001',90);
INSERT INTO `SC`(Sno,Cno,score) VALUES ('002','002',80);
INSERT INTO `SC`(Sno,Cno,score) VALUES ('002','003',70);
INSERT INTO `SC`(Sno,Cno,score) VALUES ('002','004',60);
INSERT INTO `SC`(Sno,Cno,score) VALUES ('002','005',50);
INSERT INTO `SC`(Sno,Cno,score) VALUES ('003','001',81);
INSERT INTO `SC`(Sno,Cno,score) VALUES ('003','002',82);
INSERT INTO `SC`(Sno,Cno,score) VALUES ('003','003',83);
INSERT INTO `SC`(Sno,Cno,score) VALUES ('003','004',84);
INSERT INTO `SC`(Sno,Cno,score) VALUES ('003','005',85); - 引入数据库的命令
1
[root@node1 datasets]# mysql -uroot -proot school < school.sql
- 在建立数据库之后可以先进行用户授权
1
2
3
4
5grant all on school.* to dbuser@'%' identified by '123456'
all 表示授权所有操作,增删改查
on 后面的school.* 表示school数据库的所有表
dbuser 表示授权用户名
后面的@'%'表示授权所有网段, 如'192.168.37.%'