awk:pattern scanning and processing language awk以行为处理的单位友情链接:正则表达式的初探
命令格式:awk options program file
‘条件判断1{动作1} 条件判断2{动作2}......' file_name#所用的动作都需要使用大括号,awk后面处理格式要用单引号括起来
常用参数及说明:更多详细信息可以参考man awk页面
- -F fs:--field-separator fs 使用fs作为分隔符
- -f program-file:--file program-file 读取的程序文件名
awk默认的分隔符为“空格键”或“tab键”,每一个字段都有变量来对应。$0表示一整行,$1,$2,$3....分别代表第几个字段
awk处理数据流程:
- 读入第一行,并将第一行的字段对应到 $0, $1, $2.... 等变量当中
- 依据 "条件判断",判断是否需要进行后面的 "动作"
- 做完所有的条件判断与动作
- 若后面还有行,则继续上面1~3步,直到文本中的行全部处理完
awk内建变量,注意使用这些变量的时候,和使用bash变量不同,不需要在前面加上$符号
变量 | 说明 |
---|---|
NF | 每一行($0)拥有的字段总数 |
NR | 目前awk处理的是第几行数据 |
FS | 目前的分割符,默认是空格键和Tab键 |
awk的逻辑运算符
运算符号 | 说明 |
---|---|
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
== | 等于 |
!= | 不等于 |
例子:
[root@rhel6164 ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[root@rhel6164 ~]# echo $PATH | awk '{FS=":"} {print $2}' #修改分割符为冒号,然后打印出第二个字段,因为awk在读入第一行的时候,还是使用的默认分隔符。
#所有第二个字段为空
[root@rhel6164 ~]# echo $PATH | awk '{FS=":"} {print $1}' #修改FS的值,其实对第一行没有起作用
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[root@rhel6164 ~]# echo $PATH | awk 'BEGIN{FS=":"} {print $2}' #加上BEGIN关键字后,就可以在awk读入第一行数据的时候就修改FS分隔符的值
/usr/local/bin
[root@rhel6164 ~]# echo $PATH | awk -F: '{print $1}' #-F后面接域分隔符,等同FS的值
/usr/local/sbin
awk动作内{ }也支持if条件判断
例子:
[root@rhel6164 awk]# cat test.txt
this is the first line
this is the second line
this is the third line
[root@rhel6164 awk]# awk '{if(NR==1)printf "%s\n",$4}' ./test.txt #当处理第一行的时候,打印出第四个字段
first
awk可以将多个空格和tab键作为一个分割符打印出想要的字段
例子:
[root@rhel6164 awk]# who #第一列和第二列中间多个连续的空格
root tty1 2014-06-23 14:26
root pts/0 2014-07-07 16:40 (10.121.126.154)
[root@rhel6164 awk]# who | cut -d ' ' -f1,2 #想用空格作为分隔符,cut打印出第一个和第二个字段(空格)
root
root
[root@rhel6164 awk]# who | awk '{printf "%s,%s\n",$1,$2}' #用awk就可以打印出想要的第一个和第二个字段
root,tty1
root,pts/0
awk与正则表达式一起,处理包含特定字符串的行
例子:
[root@rhel6164 awk]# cat test.txt #原始文件
this is the first line awk1
this is the second line awk2
this is the third line awk3
[root@rhel6164 awk]# awk '/first/{print $6}' ./test.txt #两个/(slash)里面可以放正则表达式,这里是搜索含有first的行,然后打印出第6个字段
awk1
[root@rhel6164 awk]# awk '!/first/{print $6}' ./test.txt #这个是上面例子的否定,打印不包含first字符串的行的第6个字段
awk2
awk3
[root@rhel6164 awk]# awk '!/(first|awk2)/{print $6}' ./test.txt #这里用了扩展正则表达式,打印不包含first或者awk2的字符串行的第6个字段
awk3
[root@rhel6164 awk]# awk '/awk/ && !/first/ {print $6}' ./test.txt #这里用了关系运算符,打印包含awk字符串,但是不包含first字符串行的第6个字段
awk2
awk3
[root@rhel6164 awk]# cat script #awk需要使用的程序放到文件里面
/awk/ && !/first/ {print $6}
[root@rhel6164 awk]# awk -f script ./test.txt #直接使用-f选项来调用文件来进行awk处理
awk2
awk3