awk
1、工作流程:
- 读取文件之前的代码段(BEGIN)
- 执行中间代码段{body}
- 读取文件后的代码段( END)
-
(图源于百度)
2、命令格式
awk -参数 BEGIN{
} '/pattern/ {body}' END {
}
逐行扫描
a、常见参数:
-F:指定分隔符号,默认的分隔符是空格或制表符(tab)
[root@shell shell.test] awk -F ":" '{print $1}' passwd # 过滤文件中的由root一行,将那行打印出来,并以:为分隔符换行打印
-f: 从指定程序文件读取AWK程序源
-v :参数传递,定义和引用变量 ,可以把外部变量引入到内部
-V :查看awk的版本号
b、三种执行方法
1、awk -参数 BEGIN{} ‘/patter/ {}’ END{} file
2、以shell脚本的形式来执行,将脚本前面的解释器换为#!/bin/awk(awk所在的路径)-f,然后在下面写脚本
3、awk -f file.awk file
:将规则写入file.awk文件里面
c、条件操作符
操作符 | 含义 |
---|---|
~ | 匹配正则表达式 |
!~ | 不匹配正则表达式 |
== != < <= > >= | 关系运算符 |
= += -= *= /= %= ^= **= | 赋值 |
| | 或运算 |
|| | 逻辑或 |
& | 与运算 |
&& | 逻辑与 |
++ – | 增加或减少,作为前缀或后缀 |
$ | 字段引用 |
in | 数组成员 |
d、内置参数
内置变量 | 描述 |
---|---|
ARGC | 命令行参数个数 |
ARGV | 命令行参数排列 |
ENVIRON | 包含当前环境的值的数组 |
FILENAME | 当前输入文件的名称 |
FNR | 当前输入文件的输入记录数 |
FS | 输入字段分隔符,默认情况下为一个空格 |
NF | 在当前输入记录中的字段的数目 |
NR | 已读的记录数 |
OFS | 输出字段分隔符 |
ORS | 输出记录分隔符 |
RS | 输入记录分隔符,默认情况下为一个换行符 |
OFMT | 用于数字的输出格式 |
RT | 记录终止符 |
RSTART | 匹配第一个字符的索引 |
RLENGTH | 匹配字符串长度 |
SUBSEP | 字符用于分隔多个标在数组中的元素,默认情况下是“\034” |
TEXTDOMAIN | awk程序的文本域 |
ARGIND | 当前文件的ARGV索引正在处理中 |
BINMODE | 在排POSIX系统上,指定使用“二进制”模式下所有的文件I/O |
CONVFMT | 用于数字的转换格式,默认情况下是“%.6g” |
IGNORECASE | 控制所有的正则表达式和字符串操作区分大小写 |
PROCINFO | 提供数组的元素访问运行AWK程序有关信息 |
字符串常量
字符串常量 | 描述 |
---|---|
| 反斜线 | |
\a | alert字符,通常为ASCII BEL字符 |
\b | 退格键 |
\f | 换页 |
\n | 换行符 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\xhex digits | 字符由十六进制数字下面的\x中的字符串来表示 |
\c | 字面字符c |
d、注意
- 域:分隔符隔开的参数
- awk里输出内置变量不用加$,只有域标识才加$
- 在输出时$0,表示把全文内容全部输出,$1,表示输出第一个域,
- 在匹配成功后,才会执行命令
- BGEGIN:在开始时只会执行一次,且必须大写,可以在里面定义变量后面就可以用
- body部分得用单引号引起来,里面是动作
- /patter/可以指定模式来处理,如果不指定则全部处理
- awk语句是由模式和动作组成的
- program要放在单引号里,放在双引号里默认打印全部
3、练习题
1、以冒号:为分隔符,匹配root或者sync的行
[root@shell shell.test] awk -F: '/root|sync/' passwd
2、以冒号为分隔符号,匹配root或者rsync,且只输出第1个域
[root@shell shell.test] awk -F: '/root|sync/{print $1}' passwd
[root@shell shell.test] awk -F: '/root|sync/{print $0}' passwd # 输出匹配的行
[root@shell shell.test] awk -F: '/root|sync/{print $1$3}' passwd #输出匹配的第1和第3个域
3、取出/下的容量
[root@shell shell.test] df -h |grep '^/' |awk '{print $2}'
4、匹配passwd文件里面的以root开头的以冒号分割的第一个域
awk 'BEGIN{FS=":"} /^root/{print $1}' /etc/passwd # FS是输入分割字符
awk 'BEGIN{FS=":"} /^root/{print $1 $3}' /etc/passwd # 取出第一第三个域
awk -F: '/^root/ {print $1}' /etc/passwd #和第一个一个效果
5、开头和结尾要打印出分割线
[root@shell shell.test] awk -F: 'BEGIN{print"-----------"} /^root/{print $1}END{print"-----------"}' /etc/passwd
-----------
root
-----------
7、打印出和文件一样行的hello
awk '{print "hello "}' /etc/passwd
8、打印出第一第第三列用TAB来分割
awk -F: '{print $1"\t"$3}' /etc/passwd
31