awk 命令
2018-05-09 本文已影响14人
analanxingde
基本模式awk '{pattern + action}' {filenames}
awk、grep、sed
是linux操作文本的三大利器,也是必须掌握的linux命令之一。三者的功能都是处理文本,但侧重点各不相同,其中属awk功能最强大,但也最复杂。grep
更适合单纯的查找或匹配文本,sed
更适合编辑匹配到的文本,awk
更适合格式化文本,对文本进行较复杂格式处理。
awk参数
- -F 指定输入文件折分隔符,如-F:
- -v 赋值一个用户定义变量,如-va=1
- -f 从脚本文件中读取awk命令
本文中例子awktest.text
具体内容为
20170102 admin,password Open
20170801 nmask,nmask close
20180902 nm4k,test filter
分隔符
- 默认分隔符为“ ”
[root@bgpcluster ~ ]$ awk '{print $1,$3}' awktest.text
//或者$ cat awktest.text | awk '{print $1,$3}'
20180502 Open
20180501 close
20180502 filter
- 自定义分隔符
[root@bgpcluster ~ ]$ awk -F, '{print $2}' awktest.text
password Open
nmask close
test filter
- 使用多个分隔符,先使用空格分割,然后对分割结果再使用”,”分割
[root@bgpcluster ~ ]$ awk -F '[ ,]' '{print $1,$2,$3}' awktest.text
20180502 admin password
20180501 nmask nmask
20180502 nm4k test
设置变量
设置awk自定义变量,用参数-v
- 例1:设置变量a为1
[root@bgpcluster ~ ]$ cat awktest.text| awk -v a=1 '{print $1,$1+a}'
20180502 20180503
20180501 20180502
20180502 20180503
- 例2:字符串拼接:(用””而不是+)
[root@bgpcluster ~ ]$ cat awktest.text | awk -v a=\" '{print a""$0""a}'
"20180502 admin,password Open"
"20180501 nmask,nmask close"
"20180502 nm4k,test filter"
逻辑判断
- 输出第一列为20180502的记录
[root@bgpcluster ~ ]$ cat awktest.text|awk '$1==20180502 {print}'
20180502 admin,password Open
20180502 nm4k,test filter
内置变量
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行 -F选项
NF 浏览记录的域的个数,即列数
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
例子:
$ awk -F ' ' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' awktest.text
filename:awktest.text,linenumber:1,columns:3,linecontent:20180502 admin,password Open
filename:awktest.text,linenumber:2,columns:3,linecontent:20180501 nmask,nmask close
filename:awktest.text,linenumber:3,columns:3,linecontent:20180502 nm4k,test filter
在上述例子中,可以用printf代替print,更加简便
awk -F ' ' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' awktest.text
内置函数
- substr字符串截取:截取第一列的第一到第四个字符
$ awk '{print substr($1,1,4)}' awktest.text
- split切分字符串:以逗号分隔第2列的数据,并输出分别输出第2列的内容
$ awk '{split($2,a,",");print a[1],a[2]}' awktest.text
- gsub替换:将第2列中的nmask替换成nMask
$ awk '{gsub("nmask","nMask",$2);print}' awktest.text
awk编程
begin块与end块
通常,对于每个输入行, awk 都会执行每个脚本代码块一次。然而,在许多编程情况中,可能需要在 awk 开始处理输入文件中的文本之前执行初始化代码。对于这种情况, awk 允许您定义一个 BEGIN 块。
因为 awk 在开始处理输入文件之前会执行 BEGIN 块,因此它是初始化 FS(字段分隔符)变量、打印页眉或初始化其它在程序中以后会引用的全局变量的极佳位置。
awk 还提供了另一个特殊块,叫作 END 块。 awk 在处理了输入文件中的所有行之后执行这个块。通常, END 块用于执行最终计算或打印应该出现在输出流结尾的摘要信息。
- 例子:
$ awk 'BEGIN {count=0;print "[start] count is ", count} {count=count+1;print $0;} END{print "[end]count is ", count}' awktest.text
若没有begin初始化,则count的默认值也为0
awk文件编程
可以将要执行的awk命令放入一个file中,然后用awk -f
来调用文件。
例如:
[root@bgpcluster ~ ]$ cat awk.txt
#!/bin/awk
BEGIN {
FS="\n"
RS=""
ORS="\n\n"
}
{
print $1","$2","$3
}
[root@bgpcluster ~ ]$ awk -f awk.txt awktest.text
20180502 admin,password Open,20180501 nmask,nmask close,20180502 nm4k,test filter