目录
1. 初识 awk
1.1 awk 命令格式
awk
的基本格式如下:
awk option program file
awk
选项如下:
选项 | 描述 |
---|---|
-F fs | 指定字段分隔符 |
-f file | 从指定文件中读取程序 |
-v var=value | 定义 awk 程序中一个变量 |
-mf N | 指定要处理数据文件的最大字段数 |
-mr N | 指定数据文件最大数据行数 |
1.2 使用数据字段变量
awk
会自动给每一行中每个数据分配一个变量,如$0
代表文本自身,$1
代表第一个字段,$2
代表第二个字段,以此类推,例:
[root@localhost tmp]# cat data2
This is the first line of the test data
This is the second line of the test data
This is the third line of the test data
#打印第四个字段,默认 awk 以空格为字段分隔符
[root@localhost tmp]# awk '{print $4}' data2
first
second
third
1.3 使用多个命令
在awk
中使用多个命令时需要用;
隔开,例:
[root@localhost tmp]# echo This is windows |awk '{$3="linux"; print$0}'
This is linux
1.4 从文件中读取命令
从文件中读取命令用f + 读取的文件
,例:
[root@localhost tmp]# cat script1
{print $1}
[root@localhost tmp]# awk -f script1 data2
This
This
This
1.5 处理数据前运行脚本
在处理数据前需要运行脚本时加BEGIN
关键词,例:
[root@localhost tmp]# cat data2
This is the first line of the test data
This is the second line of the test data
This is the third line of the test data
#打印文本第四个字段前先打印 Hello World
[root@localhost tmp]# awk 'BEGIN{print "Hello World"}{print $4}' data2
Hello World
first
second
third
1.6 处理数据后运行脚本
在处理数据后需要运行脚本时加END
关键词,例:
#打印文本第四个字段后再打印 bye!
[root@localhost tmp]# awk '{print $4}END{print "bye!"}' data2
first
second
third
bye!
2. awk与正则表达式
2.1 问号
问好?
表示前面字符出现 0 次或 1 次,不会匹配出现多次的字符,例:
[root@localhost tmp]# echo wd |awk '/w?d/{print $0}'
wd
[root@localhost tmp]# echo wod |awk '/wo?d/{print $0}'
wod
此外?
还可以与[]
一起使用,例:
[root@localhost tmp]# echo wod |awk '/wo[ab]?d/{print $0}'
wod
[root@localhost tmp]# echo wod |awk '/w[ox]?d/{print $0}'
wod
2.2 加号
加好+
表示前面字符至少出现一次或者多次,例:
[root@localhost tmp]# echo wod |awk '/wo+d/{print $0}'
wod
[root@localhost tmp]# echo wd |awk '/wo+d/{print $0}'
[root@localhost tmp]#
[root@localhost tmp]# echo woood |awk '/wo+d/{print $0}'
woood
2.3 花括号
花括号{}
表示可以重复前一个字符的范围,这里通常要与--re-interval
连用,表达式如下:
awk --re-interval '/A{m,n}/{print $0}'
#m表示匹配 m 次,n 表示最多匹配 n 次
例:
[root@localhost tmp]# echo "wood" |awk --re-interval '/wo{1,3}d/{print $0}'
wood
[root@localhost tmp]# echo "wood" |awk --re-interval '/wo{2}d/{print $0}'
wood
此外。花括号也能与[]
连用。
2.4 管道符号
管道符号|
可以允许在检查数据流时,用逻辑或的方式匹配两个或多个模式,例:
[root@localhost tmp]# echo “tom and jerry” |awk '/tom | bob/{print $0}'
“tom and jerry”
[root@localhost tmp]# echo “tom and jerry” |awk '/tom | jerry/{print $0}'
“tom and jerry”
2.5 分组表达式
分组表达式用()
表示,可以将正则表达式模式分组,例:
[root@localhost tmp]# echo wood |awk '/(w|v)oo(d|e)/{print $0}'
wood
3. awk进阶
3.1 字段与分隔符变量
下面是awk
的数据字段和记录变量:
变量 | 描述 |
---|---|
FIELDWIDTHS | 定义每个数据字段的宽度 |
FS | 输入字段分隔符 |
RS | 输入记录分隔符 |
OFS | 输出字段分隔符 |
ORS | 输出记录fen’ge’fu |
例:
#FS 输入字段分隔
[root@localhost tmp]# cat data4
linux1,windows1,MacOS1
linux2,windows2,MacOS2
linux3,windows3,MacOS3
[root@localhost tmp]# awk 'BEGIN{FS=","}{print $2,$3}' data4
windows1 MacOS1
windows2 MacOS2
windows3 MacOS3
#FS 与 OFS
[root@localhost tmp]# awk 'BEGIN{FS=",";OFS=" - "}{print $2,$3}' data4
windows1 - MacOS1
windows2 - MacOS2
windows3 - MacOS3
#FIELDWIDTHS
[root@localhost]# echo "123456789" |awk 'BEGIN{FIELDWIDTHS="3 3 3"}{print $1,$2,$3}'
123 456 789
# FS 与 RS
[root@localhost tmp]# cat data5
AAAA
aaaa
1111
BBBB
bbbb
2222
[root@localhost tmp]# awk 'BEGIN{FS="\n";RS=""}{print $1,$3}' data5
AAAA 1111
BBBB 2222
3.2 使用模式
3.2.1 正则表达式
在使用正则表达式时,表达式应出现在控制程序的花括号前面,例:
[root@localhost tmp]# cat data4
linux1,windows1,MacOS1
linux2,windows2,MacOS2
linux3,windows3,MacOS3
[root@localhost tmp]# awk 'BEGIN{FS=","} /.*2/{print $2}' data4
windows2
3.2.2 匹配操作符
匹配操作符用波浪号表示~
,它允许指定匹配操作符,数据字段,要匹配的正则表达式,例:
[root@localhost tmp]# cat data4
linux1,windows1,MacOS1
linux2,windows2,MacOS2
linux3,windows3,MacOS3
[root@localhost tmp]# awk -F, '$1~/.*2/{print $1,$3}' data4
linux2 MacOS2
此外如果表示不匹配此模式时,前面加!
即可,例:
[root@localhost tmp]# awk -F, '$1!~/.*2/{print $1,$3}' data4
linux1 MacOS1
linux3 MacOS3
3.2.3 数学表达式
awk
中常见的数学比较表达式有:
- x == y
- x <= y
- x < y
- x > y
- x >= y
例:
[root@localhost tmp]# cat /etc/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
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@localhost tmp]# awk -F: '$3 == 0{print $1}' /etc/passwd
root
3.3 格式化打印
awk
中格式化打印用printf
,常用的格式化字符如下:
控制字符 | 描述 |
---|---|
c | 将数字所谓 ASCII 字符显示 |
d | 显示一个整数值 |
e | 科学计数法显示 |
f | 显示浮点数 |
o | 显示一个八进制 |
s | 显示一个文本字符串 |
x | 显示一个十六进制值 |
width | 指定输出字段最小值,如果短语此值,用空格填充 |
prec | 指定浮点数中小数后面显示的位数 |
- | 指明数据是左对齐 |
例:
[root@localhost tmp]# cat data5
AAAA
aaaa
1111
BBBB
bbbb
2222
[root@localhost tmp]# awk 'BEGIN{FS="\n";RS=""}{printf "%16s %s\n",$1,$3}' data5
AAAA 1111
BBBB 2222
[root@localhost tmp]# awk 'BEGIN{FS="\n";RS=""}{printf "%-16s %s\n",$1,$3}' data5
AAAA 1111
BBBB 2222