1、语法和参数说明
语法
awk [options] 'script' var=value file(s)
或
awk [options] -f scriptfile var=value file(s)
或
awk [options] 'pattern{action}' FILE ....
选项参数说明:
-F fs or --field-separator fs
指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:。
-v var=value or --asign var=value
赋值一个用户定义变量。
-f scripfile or --file scriptfile
从脚本文件中读取awk命令。
-mf nnn and -mr nnn
对nnn值设置内在限制,-mf选项限制分配给nnn的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。
-W compact or --compat, -W traditional or --traditional
在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样,所有的awk扩展都被忽略。
-W copyleft or --copyleft, -W copyright or --copyright
打印简短的版权信息。
-W help or --help, -W usage or --usage
打印全部awk选项和每个选项的简短说明。
-W lint or --lint
打印不能向传统unix平台移植的结构的警告。
-W lint-old or --lint-old
打印关于不能向传统unix平台移植的结构的警告。
-W posix
打开兼容模式。但有以下限制,不识别:/x、函数关键字、func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;操作符**和**=不能代替^和^=;fflush无效。
-W re-interval or --re-inerval
允许间隔正则表达式的使用,参考(grep中的Posix字符类),如括号表达式[[:alpha:]]。
-W source program-text or --source program-text
使用program-text作为源代码,可与-f命令混用。
-W version or --version
打印bug报告信息的版本。
其中pattern包括以下几种:
地址定界
模式(包括正则表达式)
表达式
BEGIN(命令执行前预处理操作)
END(命令执行后的操作)
pattern通过,才会执行{action},当然pattern也可以省去,不匹配只执行动作。
action:
定义变量(数组)
语句(if、while、for)
输出(print、printf)
awk内置的变量:
NF : 当前处理行一共多少字段
FS : 输入字段分隔符,默认空格
OFS : 输出字段分隔符,默认空格
NR : 目前awk所处理的是第几行数据
2、基本用法
示例1:
打印用户为apache和zabbix用户的用户名、UID、处理行的字段总数、输出行处于文件的第几行、输出符合条件的行最后一列
方法1:
# awk -F: 'BEGIN{OFS="*"} /^apache|^zabbix/ {print $1,$3,NF,NR,$NF}' /etc/passwd
zabbix*498*7*30*/sbin/nologin
apache*48*7*36*/sbin/nologin
方法2:
# awk 'BEGIN{FS=":";OFS="*"} /^apache|^zabbix/ {print $1,$3,NF,NR,$NF}' /etc/passwd
zabbix*498*7*30*/sbin/nologin
apache*48*7*36*/sbin/nologin
解析:
分隔符:有两种表示方法,如方法1所示使用-F跟分隔符的方式,方法2中和输出分隔符OFS一块放入BEGIN{}模块,默认输出分隔符是空格。
NF:
表示文件内容的列数,所以$NF就表示最后一列。
模式:
/^apache|^zabbix/ 就是模式的匹配,模式写入//就可以,表示匹配以apache或者zabbix开头的行。
BEGIN:
在awk实际工作之前执行一次
举例:
# awk 'BEGIN{FS=":"} {print $1,$3}' /etc/passwd
root 0
bin 1
...
# awk '{FS=":"} {print $1,$3}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin 1
...
可以看到第二个输出结果和第一个结果不一样,因为BEGIN的工作流程是这样的:1、没有BEGIN出现,不用事前执行一些动作;2、awk开始获取第一行数据,以FS值为分隔符,此时的FS是空的,$0变量保存整行数据,$1保存第一个字段数据,$2保存第二个字段数据.........一直到最后;3、awk开始执行动作,FS=":" ---> 显示$1,$3 ---> 获取第二行数据,以FS值冒号为分隔符............。
在FS赋值之间就已经把第一行数据获取完毕了。 所以 在有BEGIN的情况下,awk在获取数据之前会执行一次BEGIN的动作, 而且只有这一次。 那么END也就不难理解了,就是在操作完所有行数据以后所执行的一次动作。
示例2:
print和printf
# awk 'BEGIN{FS=":"}NR==5,NR==8{print $1,$3,"\t\t","This is",NR,"line"}' /etc/passwd
lp 4 This is 5 line
sync 5 This is 6 line
shutdown 6 This is 7 line
halt 7 This is 8 line
解析:
NR是表示第几行,上面就是第5行到第8行的定界
在print里面除了变量以外,其它字符都要加上引号。\t表示一个制表符TAB。不同的字段输出的时候会以输出字符分隔符隔开
除了表示字段数据的$0,$1,$2等,其他变量包括自定义变量都不用$号
但是可以明显感觉上面的排版有点乱,这里可以使用printf对输出内容进行格式化。
下面进行格式化输出
# awk 'BEGIN{FS=":"}NR==5,NR==8{printf "%-10s %5s %10s %2s %5s\n",$1,$3," This is",NR,"line"}' /etc/passwd
lp 4 This is 5 line
sync 5 This is 6 line
shutdown 6 This is 7 line
halt 7 This is 8 line
解析:
格式化常用格式化字符
\n | 换行 |
\t | 水平TAB键 |
%s | 显示字符串。数值也可以当作字符串显示 |
%d,%i | 十进制整数 |
%c | 显示字符ASCLL码 |
%e,%E | 科学计数法显示数值 |
%f | 浮点数显示 |
%n.mf | n表示包括小数点在内的长度,m表示小数点后的长度 |
%% | 显示%自身 |
%u | 无符号整数 |
修饰符:
- 左对齐
+ 显示数值符号
0 以0代替多余的空格。
这里需要注意的是%-10s %5s %10s %2i%5s\n这一段就是格式化语句,%-10s:表示10个字符宽度,“-”表示左对齐,printf不会自动换行,所以后面加了个\n。
示例3:表达式
匹配UID大于等于500的相应信息
# awk 'BEGIN{FS=":"}$3>=500{printf "%-10s %5s %10s %2s %5s\n",$1,$3,"This is",NR,"line"}' /etc/passwd
nfsnobody 65534 This is 23 line
nexus 500 This is 31 line
box 501 This is 32 line
示例4:添加说明
对上面的输出添加说明
# awk 'BEGIN{FS=":";printf "%-10s %5s %12s %17s\n","USER","UID","SHELL","DESCRIPTION"}/bin\/bash\>/{printf "%-10s %5s %15s %10s %2i%5s\n",$1,$3,$7,"This is",NR,"line"}' passwd
USER UID SHELL DESCRIPTION
root 0 /bin/bash This is 1 line
nexus 500 /bin/bash This is 31 line
...
示例5:算数和自定义变量
计算同学总成绩
# cat test.txt
User English Math Music
zhangsan 85 90 83
lisi 80 95 60
zhouwu 66 77 98
zhengwang 80 93 67
# awk 'NR==1{printf "%-10s %7s %6s %6s %6s\n",$1,$2,$3,$4,"Total"}NR>=2{total=$2+$3+$4;printf "%-10s %7s %6s %6s %6s\n",$1,$2,$3,$4,total}' test.txt
User English Math Music Total
zhangsan 85 90 83 258
lisi 80 95 60 235
zhouwu 66 77 98 241
zhengwang 80 93 67 240
解析:
NR==1表示第一行在第五列定义了一个字符串“Total”,也就是定义了一个变量。
NR>=2之后的内容表示当行数大于等于2的时候,每一行的Total的值等于第二列第三列和第四列的值相加。
未完待续...
参考:
http://f.dataguru.cn/thread-509133-1-1.html