原 运维利器之AWK 蔡佳娃

功能

一个行文本处理工具,可以逐行处理文件中的数据。

语法

本文中提到的cjw.txt内容大致如下:

Installing fontpackages-filesystem-1.41-1.1.el6.noarch
warning: fontpackages-filesystem-1.41-1.1.el6.noarch: Header V3 RSA/SHA256 Signature, key ID c105b9de: NOKEY
Installing liberation-fonts-common-1.05.1.20090721-5.el6.noarch
Installing xml-common-0.6.3-32.el6.noarch
Installing iso-codes-3.16-2.el6.noarch
Installing setup-2.8.14-20.el6.noarch
Installing filesystem-2.4.30-3.el6.i686
Installing dejavu-fonts-common-2.30-2.el6.noarch
Installing xkeyboard-config-2.6-6.el6.noarch
Installing control-center-filesystem-2.28.1-38.el6.i686
Installing paktype-fonts-common-2.0-8.el6.noarch

语法说明

awk 'pattern + {action}'

desc:
1. 单引号''是为了和shell命令区分开
2. 大括号{}表示一个命令分组
3. pattern是一个过滤器,表示符合pattern的行才进行action处理
4. action是处理动作
5. 使用#作为注释

eg.
#显示cjw.txt中的第三行到第五行
awk 'NR==3,NR==5{print}' cjw.txt

#输出
Installing liberation-fonts-common-1.05.1.20090721-5.el6.noarch
Installing xml-common-0.6.3-32.el6.noarch
Installing iso-codes-3.16-2.el6.noarch

常用命令选项

-F fs fs指定输入分隔符,fs可以是字符串或正则表达式,如-F:

-v var=value 赋值一个用户定义变量,将外部变量传递给awk

-f scripfile 从脚本文件中读取awk命令

-m[fr] val 对val值设置内在限制

pattern说明

pattern参数可以是grep正则中的一个,正则使用/pattern/。

#显示cjw.txt中,正则匹配Install的行
awk '/Install/' cjw.txt

#输出
Installing fontpackages-filesystem-1.41-1.1.el6.noarch
Installing liberation-fonts-common-1.05.1.20090721-5.el6.noarch
Installing xml-common-0.6.3-32.el6.noarch
Installing iso-codes-3.16-2.el6.noarch
...

pattern和action可以只有其一,但不能两者都没有,默认的action是print。

#显示cjw.txt中,长度大于80行的内容
awk 'length($0)>80' cjw.txt
#等价于
awk 'length($0)>80 {print $0}' cjw.txt


#显示cjw.txt中,长度大于80的行号和内容
awk 'length($0)>80 {print NR, $0}' cjw.txt

#输出
2 warning: fontpackages-filesystem-1.41-1.1.el6.noarch: Header V3 RSA/SHA256 Signature, key ID c105b9de: NOKEY

内置变量

#显示cjw.txt中第3行到第5行的第一列与最后一列
awk 'NR==3,NR==5{print $1,$NF}' cjw.txt

#输出
Installing liberation-fonts-common-1.05.1.20090721-5.el6.noarch
Installing xml-common-0.6.3-32.el6.noarch
Installing iso-codes-3.16-2.el6.noarch


#按定界符"-"分割每行的内容,然后打印输出第一列和第二列
awk 'BEGIN{FS="-"}{print $1,$2}' cjw.txt

#输出
Installing fontpackages filesystem
warning: fontpackages filesystem
Installing liberation fonts
Installing xml common
Installing iso codes
Installing setup 2.8.14

内置函数

#将文本中的Installing替换为cjw,输出可以替换的行号以及替换后的内容
awk 'gsub("Installing", "cjw"){print NR, $0}' cjw.txt

#输出
1 cjw fontpackages-filesystem-1.41-1.1.el6.noarch
3 cjw liberation-fonts-common-1.05.1.20090721-5.el6.noarch
4 cjw xml-common-0.6.3-32.el6.noarch
5 cjw iso-codes-3.16-2.el6.noarch
...


#输出cjw.txt文本中的包含common的行号及其行内容
awk 'match($0,"common") {print NR, $0}' cjw.txt

#输出
3 Installing liberation-fonts-common-1.05.1.20090721-5.el6.noarch
4 Installing xml-common-0.6.3-32.el6.noarch
8 Installing dejavu-fonts-common-2.30-2.el6.noarch
11 Installing paktype-fonts-common-2.0-8.el6.noarch
...

操作符

支持+、-、*、、、%、++、-、+=等运算操作。支持==、!=、>、~等判断操作。

控制语句

BEGIN和END本质是一个pattern。BEGIN用于awk程序开始开始前,做一些初始化的工作;END用于awk程序结束前,做一些收尾的工作。

流程控制语句与其他语言几乎相同,就不在此赘述。

#使用空格将info进行切割,输出切割后数组的长度以及函数split的返回值
awk 'BEGIN{info="it is a test";lens=split(info,tA," "); print length(tA),lens;}'

#输出
4 4


#控制流的使用
awk 'BEGIN { 
    test=100; 
    if (test>90) { 
        print "very good"; 
    } else if (test>60) { 
        print "good"; } 
    else { 
        print "no pass"; 
    } 
}'

#输出
very good
发布于:2019-11-09 11:39:17